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?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay