Grep not working with variables, even with quotes

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
-2
down vote

favorite












name=$(echo "$FILENAME" | grep -E '*.(eng|por|pt-BR).*')



Why this line doesn't work?



if I do



echo "Test (2013).1080p.por.mkv" | grep -E "*.(eng|por).*"



It works, I tried with "" without " and with ' in my script and it seems like it's not getting piped to grep. I don't know why? I'm using bash.



FILENAME="Test (2013).1080p.por.mkv"



I want to grab only .por. or .eng in a file







share|improve this question






















  • Are you literally running that first line as-is? Are you sure that the FILENAME variable isn't empty?
    – igal
    Nov 6 '17 at 12:09






  • 2




    In what way does it not work? Is $name empty? How do you check it? Do you get an error?, What do you get if you replace grep -E ... with sed -n l? What do you expect to achieve with that command? What about doing case $FILENAME in (*.eng.* | *.por.* | *.pt-BR.*) ...; esac?
    – Stéphane Chazelas
    Nov 6 '17 at 12:29











  • @StéphaneChazelas no error, it's just printed the entire variable. Yes $name is empty and I set $FILENAME before it with FILENAME="Test (2013) [HDTV-720p].bluray.1080p.por.mkv"
    – Freedo
    Nov 6 '17 at 12:30














up vote
-2
down vote

favorite












name=$(echo "$FILENAME" | grep -E '*.(eng|por|pt-BR).*')



Why this line doesn't work?



if I do



echo "Test (2013).1080p.por.mkv" | grep -E "*.(eng|por).*"



It works, I tried with "" without " and with ' in my script and it seems like it's not getting piped to grep. I don't know why? I'm using bash.



FILENAME="Test (2013).1080p.por.mkv"



I want to grab only .por. or .eng in a file







share|improve this question






















  • Are you literally running that first line as-is? Are you sure that the FILENAME variable isn't empty?
    – igal
    Nov 6 '17 at 12:09






  • 2




    In what way does it not work? Is $name empty? How do you check it? Do you get an error?, What do you get if you replace grep -E ... with sed -n l? What do you expect to achieve with that command? What about doing case $FILENAME in (*.eng.* | *.por.* | *.pt-BR.*) ...; esac?
    – Stéphane Chazelas
    Nov 6 '17 at 12:29











  • @StéphaneChazelas no error, it's just printed the entire variable. Yes $name is empty and I set $FILENAME before it with FILENAME="Test (2013) [HDTV-720p].bluray.1080p.por.mkv"
    – Freedo
    Nov 6 '17 at 12:30












up vote
-2
down vote

favorite









up vote
-2
down vote

favorite











name=$(echo "$FILENAME" | grep -E '*.(eng|por|pt-BR).*')



Why this line doesn't work?



if I do



echo "Test (2013).1080p.por.mkv" | grep -E "*.(eng|por).*"



It works, I tried with "" without " and with ' in my script and it seems like it's not getting piped to grep. I don't know why? I'm using bash.



FILENAME="Test (2013).1080p.por.mkv"



I want to grab only .por. or .eng in a file







share|improve this question














name=$(echo "$FILENAME" | grep -E '*.(eng|por|pt-BR).*')



Why this line doesn't work?



if I do



echo "Test (2013).1080p.por.mkv" | grep -E "*.(eng|por).*"



It works, I tried with "" without " and with ' in my script and it seems like it's not getting piped to grep. I don't know why? I'm using bash.



FILENAME="Test (2013).1080p.por.mkv"



I want to grab only .por. or .eng in a file









share|improve this question













share|improve this question




share|improve this question








edited Nov 6 '17 at 12:32

























asked Nov 6 '17 at 12:04









Freedo

402417




402417











  • Are you literally running that first line as-is? Are you sure that the FILENAME variable isn't empty?
    – igal
    Nov 6 '17 at 12:09






  • 2




    In what way does it not work? Is $name empty? How do you check it? Do you get an error?, What do you get if you replace grep -E ... with sed -n l? What do you expect to achieve with that command? What about doing case $FILENAME in (*.eng.* | *.por.* | *.pt-BR.*) ...; esac?
    – Stéphane Chazelas
    Nov 6 '17 at 12:29











  • @StéphaneChazelas no error, it's just printed the entire variable. Yes $name is empty and I set $FILENAME before it with FILENAME="Test (2013) [HDTV-720p].bluray.1080p.por.mkv"
    – Freedo
    Nov 6 '17 at 12:30
















  • Are you literally running that first line as-is? Are you sure that the FILENAME variable isn't empty?
    – igal
    Nov 6 '17 at 12:09






  • 2




    In what way does it not work? Is $name empty? How do you check it? Do you get an error?, What do you get if you replace grep -E ... with sed -n l? What do you expect to achieve with that command? What about doing case $FILENAME in (*.eng.* | *.por.* | *.pt-BR.*) ...; esac?
    – Stéphane Chazelas
    Nov 6 '17 at 12:29











  • @StéphaneChazelas no error, it's just printed the entire variable. Yes $name is empty and I set $FILENAME before it with FILENAME="Test (2013) [HDTV-720p].bluray.1080p.por.mkv"
    – Freedo
    Nov 6 '17 at 12:30















Are you literally running that first line as-is? Are you sure that the FILENAME variable isn't empty?
– igal
Nov 6 '17 at 12:09




Are you literally running that first line as-is? Are you sure that the FILENAME variable isn't empty?
– igal
Nov 6 '17 at 12:09




2




2




In what way does it not work? Is $name empty? How do you check it? Do you get an error?, What do you get if you replace grep -E ... with sed -n l? What do you expect to achieve with that command? What about doing case $FILENAME in (*.eng.* | *.por.* | *.pt-BR.*) ...; esac?
– Stéphane Chazelas
Nov 6 '17 at 12:29





In what way does it not work? Is $name empty? How do you check it? Do you get an error?, What do you get if you replace grep -E ... with sed -n l? What do you expect to achieve with that command? What about doing case $FILENAME in (*.eng.* | *.por.* | *.pt-BR.*) ...; esac?
– Stéphane Chazelas
Nov 6 '17 at 12:29













@StéphaneChazelas no error, it's just printed the entire variable. Yes $name is empty and I set $FILENAME before it with FILENAME="Test (2013) [HDTV-720p].bluray.1080p.por.mkv"
– Freedo
Nov 6 '17 at 12:30




@StéphaneChazelas no error, it's just printed the entire variable. Yes $name is empty and I set $FILENAME before it with FILENAME="Test (2013) [HDTV-720p].bluray.1080p.por.mkv"
– Freedo
Nov 6 '17 at 12:30










2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










grep is the tool to print (whole) lines matching a pattern. It's not appropriate to extract parts of a string (though some grep implementations have -o<n> or -o options that can be used in some cases for that).



Here, you can use expr:



name=$(expr " $FILENAME" : '.*.(eng).' '|' 
" $FILENAME" : '.*.(por).' '|'
" $FILENAME" : '.*.(pt-PT).')


(for foo.por.eng.bar, gives priority to eng over por over pt-PT).



Some expr implementations like GNU expr also support:



name=$(expr " $FILENAME" : '.*.(eng|por|pt-PT).')


(here returns the rightmost occurrence if there are several in the filename)



With GNU grep or compatible:



name=$(
printf '%sn' "$FILENAME" |
grep -Po '.K(eng|por|pt-PT)(?=.)' |
head -n 1
)


(returns first occurrence, replace head with tail for last)



Or you could use your shell's case construct and not run any command at all:



case $FILENAME in
(*.por.*) name=por;;
(*.eng.*) name=eng;;
(*.pt-PT.*) name=pt-PT;;
esac


With bash:



re='.(por|eng|pt-PT).'
[[ $FILENAME =~ $re ]]
name=$BASH_REMATCH[1]


(first occurrence. With zsh, replace BASH_REMATCH with match)






share|improve this answer






















  • Why it's not appropriated if it seems everyone uses it?
    – Freedo
    Nov 6 '17 at 12:37










  • one point is that it will not filter correctly, it will catch literals too like "[HDTV-720p].bluray.1080p.(eng|por|pt-BR).mkv"
    – RomuloPBenedetti
    Nov 6 '17 at 12:43










  • thanks! expr seems also much easier to learn and use, and it worked both in situations where I had "eng" words in my filename but the a .por.srt file. It had a 100% success in those kind of tests so thank you so much.
    – Freedo
    Nov 6 '17 at 12:45










  • what if I wanted to apply this to a variable that is a directory?
    – Freedo
    Nov 6 '17 at 13:07










  • @Freedo, not sure what you mean, that's just string manipulation, it doesn't care whether that string is a path to a directory or any other type of file.
    – Stéphane Chazelas
    Nov 6 '17 at 13:13


















up vote
1
down vote













Assuming the file names are like Some name.por.mkv, with the final extension fixed, you could use the POSIX shell string operations, too:



$ echo "$FILENAME"
Test (2013).1080p.por.mkv
$ x=$FILENAME%.mkv; echo "$x##*."
por


Here, $var%.mkv removes the trailing .mkv, and $var##*. removes everything up to the (now) last dot. You could change the first expansion to handle other extensions by changing .mkv to just .*.






share|improve this answer




















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f402818%2fgrep-not-working-with-variables-even-with-quotes%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    grep is the tool to print (whole) lines matching a pattern. It's not appropriate to extract parts of a string (though some grep implementations have -o<n> or -o options that can be used in some cases for that).



    Here, you can use expr:



    name=$(expr " $FILENAME" : '.*.(eng).' '|' 
    " $FILENAME" : '.*.(por).' '|'
    " $FILENAME" : '.*.(pt-PT).')


    (for foo.por.eng.bar, gives priority to eng over por over pt-PT).



    Some expr implementations like GNU expr also support:



    name=$(expr " $FILENAME" : '.*.(eng|por|pt-PT).')


    (here returns the rightmost occurrence if there are several in the filename)



    With GNU grep or compatible:



    name=$(
    printf '%sn' "$FILENAME" |
    grep -Po '.K(eng|por|pt-PT)(?=.)' |
    head -n 1
    )


    (returns first occurrence, replace head with tail for last)



    Or you could use your shell's case construct and not run any command at all:



    case $FILENAME in
    (*.por.*) name=por;;
    (*.eng.*) name=eng;;
    (*.pt-PT.*) name=pt-PT;;
    esac


    With bash:



    re='.(por|eng|pt-PT).'
    [[ $FILENAME =~ $re ]]
    name=$BASH_REMATCH[1]


    (first occurrence. With zsh, replace BASH_REMATCH with match)






    share|improve this answer






















    • Why it's not appropriated if it seems everyone uses it?
      – Freedo
      Nov 6 '17 at 12:37










    • one point is that it will not filter correctly, it will catch literals too like "[HDTV-720p].bluray.1080p.(eng|por|pt-BR).mkv"
      – RomuloPBenedetti
      Nov 6 '17 at 12:43










    • thanks! expr seems also much easier to learn and use, and it worked both in situations where I had "eng" words in my filename but the a .por.srt file. It had a 100% success in those kind of tests so thank you so much.
      – Freedo
      Nov 6 '17 at 12:45










    • what if I wanted to apply this to a variable that is a directory?
      – Freedo
      Nov 6 '17 at 13:07










    • @Freedo, not sure what you mean, that's just string manipulation, it doesn't care whether that string is a path to a directory or any other type of file.
      – Stéphane Chazelas
      Nov 6 '17 at 13:13















    up vote
    3
    down vote



    accepted










    grep is the tool to print (whole) lines matching a pattern. It's not appropriate to extract parts of a string (though some grep implementations have -o<n> or -o options that can be used in some cases for that).



    Here, you can use expr:



    name=$(expr " $FILENAME" : '.*.(eng).' '|' 
    " $FILENAME" : '.*.(por).' '|'
    " $FILENAME" : '.*.(pt-PT).')


    (for foo.por.eng.bar, gives priority to eng over por over pt-PT).



    Some expr implementations like GNU expr also support:



    name=$(expr " $FILENAME" : '.*.(eng|por|pt-PT).')


    (here returns the rightmost occurrence if there are several in the filename)



    With GNU grep or compatible:



    name=$(
    printf '%sn' "$FILENAME" |
    grep -Po '.K(eng|por|pt-PT)(?=.)' |
    head -n 1
    )


    (returns first occurrence, replace head with tail for last)



    Or you could use your shell's case construct and not run any command at all:



    case $FILENAME in
    (*.por.*) name=por;;
    (*.eng.*) name=eng;;
    (*.pt-PT.*) name=pt-PT;;
    esac


    With bash:



    re='.(por|eng|pt-PT).'
    [[ $FILENAME =~ $re ]]
    name=$BASH_REMATCH[1]


    (first occurrence. With zsh, replace BASH_REMATCH with match)






    share|improve this answer






















    • Why it's not appropriated if it seems everyone uses it?
      – Freedo
      Nov 6 '17 at 12:37










    • one point is that it will not filter correctly, it will catch literals too like "[HDTV-720p].bluray.1080p.(eng|por|pt-BR).mkv"
      – RomuloPBenedetti
      Nov 6 '17 at 12:43










    • thanks! expr seems also much easier to learn and use, and it worked both in situations where I had "eng" words in my filename but the a .por.srt file. It had a 100% success in those kind of tests so thank you so much.
      – Freedo
      Nov 6 '17 at 12:45










    • what if I wanted to apply this to a variable that is a directory?
      – Freedo
      Nov 6 '17 at 13:07










    • @Freedo, not sure what you mean, that's just string manipulation, it doesn't care whether that string is a path to a directory or any other type of file.
      – Stéphane Chazelas
      Nov 6 '17 at 13:13













    up vote
    3
    down vote



    accepted







    up vote
    3
    down vote



    accepted






    grep is the tool to print (whole) lines matching a pattern. It's not appropriate to extract parts of a string (though some grep implementations have -o<n> or -o options that can be used in some cases for that).



    Here, you can use expr:



    name=$(expr " $FILENAME" : '.*.(eng).' '|' 
    " $FILENAME" : '.*.(por).' '|'
    " $FILENAME" : '.*.(pt-PT).')


    (for foo.por.eng.bar, gives priority to eng over por over pt-PT).



    Some expr implementations like GNU expr also support:



    name=$(expr " $FILENAME" : '.*.(eng|por|pt-PT).')


    (here returns the rightmost occurrence if there are several in the filename)



    With GNU grep or compatible:



    name=$(
    printf '%sn' "$FILENAME" |
    grep -Po '.K(eng|por|pt-PT)(?=.)' |
    head -n 1
    )


    (returns first occurrence, replace head with tail for last)



    Or you could use your shell's case construct and not run any command at all:



    case $FILENAME in
    (*.por.*) name=por;;
    (*.eng.*) name=eng;;
    (*.pt-PT.*) name=pt-PT;;
    esac


    With bash:



    re='.(por|eng|pt-PT).'
    [[ $FILENAME =~ $re ]]
    name=$BASH_REMATCH[1]


    (first occurrence. With zsh, replace BASH_REMATCH with match)






    share|improve this answer














    grep is the tool to print (whole) lines matching a pattern. It's not appropriate to extract parts of a string (though some grep implementations have -o<n> or -o options that can be used in some cases for that).



    Here, you can use expr:



    name=$(expr " $FILENAME" : '.*.(eng).' '|' 
    " $FILENAME" : '.*.(por).' '|'
    " $FILENAME" : '.*.(pt-PT).')


    (for foo.por.eng.bar, gives priority to eng over por over pt-PT).



    Some expr implementations like GNU expr also support:



    name=$(expr " $FILENAME" : '.*.(eng|por|pt-PT).')


    (here returns the rightmost occurrence if there are several in the filename)



    With GNU grep or compatible:



    name=$(
    printf '%sn' "$FILENAME" |
    grep -Po '.K(eng|por|pt-PT)(?=.)' |
    head -n 1
    )


    (returns first occurrence, replace head with tail for last)



    Or you could use your shell's case construct and not run any command at all:



    case $FILENAME in
    (*.por.*) name=por;;
    (*.eng.*) name=eng;;
    (*.pt-PT.*) name=pt-PT;;
    esac


    With bash:



    re='.(por|eng|pt-PT).'
    [[ $FILENAME =~ $re ]]
    name=$BASH_REMATCH[1]


    (first occurrence. With zsh, replace BASH_REMATCH with match)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 6 '17 at 13:15

























    answered Nov 6 '17 at 12:36









    Stéphane Chazelas

    283k53521854




    283k53521854











    • Why it's not appropriated if it seems everyone uses it?
      – Freedo
      Nov 6 '17 at 12:37










    • one point is that it will not filter correctly, it will catch literals too like "[HDTV-720p].bluray.1080p.(eng|por|pt-BR).mkv"
      – RomuloPBenedetti
      Nov 6 '17 at 12:43










    • thanks! expr seems also much easier to learn and use, and it worked both in situations where I had "eng" words in my filename but the a .por.srt file. It had a 100% success in those kind of tests so thank you so much.
      – Freedo
      Nov 6 '17 at 12:45










    • what if I wanted to apply this to a variable that is a directory?
      – Freedo
      Nov 6 '17 at 13:07










    • @Freedo, not sure what you mean, that's just string manipulation, it doesn't care whether that string is a path to a directory or any other type of file.
      – Stéphane Chazelas
      Nov 6 '17 at 13:13

















    • Why it's not appropriated if it seems everyone uses it?
      – Freedo
      Nov 6 '17 at 12:37










    • one point is that it will not filter correctly, it will catch literals too like "[HDTV-720p].bluray.1080p.(eng|por|pt-BR).mkv"
      – RomuloPBenedetti
      Nov 6 '17 at 12:43










    • thanks! expr seems also much easier to learn and use, and it worked both in situations where I had "eng" words in my filename but the a .por.srt file. It had a 100% success in those kind of tests so thank you so much.
      – Freedo
      Nov 6 '17 at 12:45










    • what if I wanted to apply this to a variable that is a directory?
      – Freedo
      Nov 6 '17 at 13:07










    • @Freedo, not sure what you mean, that's just string manipulation, it doesn't care whether that string is a path to a directory or any other type of file.
      – Stéphane Chazelas
      Nov 6 '17 at 13:13
















    Why it's not appropriated if it seems everyone uses it?
    – Freedo
    Nov 6 '17 at 12:37




    Why it's not appropriated if it seems everyone uses it?
    – Freedo
    Nov 6 '17 at 12:37












    one point is that it will not filter correctly, it will catch literals too like "[HDTV-720p].bluray.1080p.(eng|por|pt-BR).mkv"
    – RomuloPBenedetti
    Nov 6 '17 at 12:43




    one point is that it will not filter correctly, it will catch literals too like "[HDTV-720p].bluray.1080p.(eng|por|pt-BR).mkv"
    – RomuloPBenedetti
    Nov 6 '17 at 12:43












    thanks! expr seems also much easier to learn and use, and it worked both in situations where I had "eng" words in my filename but the a .por.srt file. It had a 100% success in those kind of tests so thank you so much.
    – Freedo
    Nov 6 '17 at 12:45




    thanks! expr seems also much easier to learn and use, and it worked both in situations where I had "eng" words in my filename but the a .por.srt file. It had a 100% success in those kind of tests so thank you so much.
    – Freedo
    Nov 6 '17 at 12:45












    what if I wanted to apply this to a variable that is a directory?
    – Freedo
    Nov 6 '17 at 13:07




    what if I wanted to apply this to a variable that is a directory?
    – Freedo
    Nov 6 '17 at 13:07












    @Freedo, not sure what you mean, that's just string manipulation, it doesn't care whether that string is a path to a directory or any other type of file.
    – Stéphane Chazelas
    Nov 6 '17 at 13:13





    @Freedo, not sure what you mean, that's just string manipulation, it doesn't care whether that string is a path to a directory or any other type of file.
    – Stéphane Chazelas
    Nov 6 '17 at 13:13













    up vote
    1
    down vote













    Assuming the file names are like Some name.por.mkv, with the final extension fixed, you could use the POSIX shell string operations, too:



    $ echo "$FILENAME"
    Test (2013).1080p.por.mkv
    $ x=$FILENAME%.mkv; echo "$x##*."
    por


    Here, $var%.mkv removes the trailing .mkv, and $var##*. removes everything up to the (now) last dot. You could change the first expansion to handle other extensions by changing .mkv to just .*.






    share|improve this answer
























      up vote
      1
      down vote













      Assuming the file names are like Some name.por.mkv, with the final extension fixed, you could use the POSIX shell string operations, too:



      $ echo "$FILENAME"
      Test (2013).1080p.por.mkv
      $ x=$FILENAME%.mkv; echo "$x##*."
      por


      Here, $var%.mkv removes the trailing .mkv, and $var##*. removes everything up to the (now) last dot. You could change the first expansion to handle other extensions by changing .mkv to just .*.






      share|improve this answer






















        up vote
        1
        down vote










        up vote
        1
        down vote









        Assuming the file names are like Some name.por.mkv, with the final extension fixed, you could use the POSIX shell string operations, too:



        $ echo "$FILENAME"
        Test (2013).1080p.por.mkv
        $ x=$FILENAME%.mkv; echo "$x##*."
        por


        Here, $var%.mkv removes the trailing .mkv, and $var##*. removes everything up to the (now) last dot. You could change the first expansion to handle other extensions by changing .mkv to just .*.






        share|improve this answer












        Assuming the file names are like Some name.por.mkv, with the final extension fixed, you could use the POSIX shell string operations, too:



        $ echo "$FILENAME"
        Test (2013).1080p.por.mkv
        $ x=$FILENAME%.mkv; echo "$x##*."
        por


        Here, $var%.mkv removes the trailing .mkv, and $var##*. removes everything up to the (now) last dot. You could change the first expansion to handle other extensions by changing .mkv to just .*.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 6 '17 at 13:02









        ilkkachu

        50.5k677138




        50.5k677138



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f402818%2fgrep-not-working-with-variables-even-with-quotes%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Christian Cage

            How to properly install USB display driver for Fresco Logic FL2000DX on Ubuntu?