find: current filename evaluates to empty in nested command

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











up vote
0
down vote

favorite












I am trying to rename a bunch of images in a directory according to their dimensions. To that end, I am building up my command step by step, using of Imagemagik's identify command. I currently am using echo and plan to switch that to mv once echo outputs correctly.



find * -type f -exec echo "$(identify -format '%w-%h' )" ;


This outputs a bunch of empty lines. However, when I just run it without the echo directly,



find * -type f -exec identify -format '%w-%h' ;


It outputs the dimensions as expected. Why isnt the inner command executing properly?










share|improve this question





















  • Why would you want to do a command substitution and then just echo?
    – Kusalananda
    Sep 25 '17 at 20:48






  • 1




    Once I get it to echo, Im going to swap that out with a mv in order to rename the file.
    – Jeff
    Oct 11 '17 at 14:57














up vote
0
down vote

favorite












I am trying to rename a bunch of images in a directory according to their dimensions. To that end, I am building up my command step by step, using of Imagemagik's identify command. I currently am using echo and plan to switch that to mv once echo outputs correctly.



find * -type f -exec echo "$(identify -format '%w-%h' )" ;


This outputs a bunch of empty lines. However, when I just run it without the echo directly,



find * -type f -exec identify -format '%w-%h' ;


It outputs the dimensions as expected. Why isnt the inner command executing properly?










share|improve this question





















  • Why would you want to do a command substitution and then just echo?
    – Kusalananda
    Sep 25 '17 at 20:48






  • 1




    Once I get it to echo, Im going to swap that out with a mv in order to rename the file.
    – Jeff
    Oct 11 '17 at 14:57












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am trying to rename a bunch of images in a directory according to their dimensions. To that end, I am building up my command step by step, using of Imagemagik's identify command. I currently am using echo and plan to switch that to mv once echo outputs correctly.



find * -type f -exec echo "$(identify -format '%w-%h' )" ;


This outputs a bunch of empty lines. However, when I just run it without the echo directly,



find * -type f -exec identify -format '%w-%h' ;


It outputs the dimensions as expected. Why isnt the inner command executing properly?










share|improve this question













I am trying to rename a bunch of images in a directory according to their dimensions. To that end, I am building up my command step by step, using of Imagemagik's identify command. I currently am using echo and plan to switch that to mv once echo outputs correctly.



find * -type f -exec echo "$(identify -format '%w-%h' )" ;


This outputs a bunch of empty lines. However, when I just run it without the echo directly,



find * -type f -exec identify -format '%w-%h' ;


It outputs the dimensions as expected. Why isnt the inner command executing properly?







find exec






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Sep 25 '17 at 17:33









Jeff

1033




1033











  • Why would you want to do a command substitution and then just echo?
    – Kusalananda
    Sep 25 '17 at 20:48






  • 1




    Once I get it to echo, Im going to swap that out with a mv in order to rename the file.
    – Jeff
    Oct 11 '17 at 14:57
















  • Why would you want to do a command substitution and then just echo?
    – Kusalananda
    Sep 25 '17 at 20:48






  • 1




    Once I get it to echo, Im going to swap that out with a mv in order to rename the file.
    – Jeff
    Oct 11 '17 at 14:57















Why would you want to do a command substitution and then just echo?
– Kusalananda
Sep 25 '17 at 20:48




Why would you want to do a command substitution and then just echo?
– Kusalananda
Sep 25 '17 at 20:48




1




1




Once I get it to echo, Im going to swap that out with a mv in order to rename the file.
– Jeff
Oct 11 '17 at 14:57




Once I get it to echo, Im going to swap that out with a mv in order to rename the file.
– Jeff
Oct 11 '17 at 14:57










2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










Use:



find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


Explanation



The problem is with the way bash expands variables



find * -type f -exec echo "$(identify -format '%w-%h' )" ;


First bash expands what is in side $(...):



find * -type f -exec echo 'identify: unable to open image `': No such file or directory...' ;


At which point find will use the same exec statement for all commands with a rather useless argument. What you want to do is suppress the bash expansion for inside the finds exec. You can stop bash expanding things by placing them inside single quotes



find * -type f -exec echo '$(identify -format %w-%h )' ;


But here we lose expansion completely, we can inject it back by running the expression with sh -c



find * -type f -exec sh -c 'echo "$(identify -format %w-%h )"' ;


Having within the shell script can also lead to some unexpected errors when dealing with whitespace or quotes or any character special to the shell in file names. To get around this you should move the as an argument to sh with:



find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


See this question/answer for a more detailed explanation of this.



Finally you can replace the * with . to let find find the files in the current directory by itself (and include hidden ones and not fail for filenames starting with -).



Additionally, you can add the -x flag to sh to get it to print out what was it executed to help with debugging the command - this can be very noisy for a lot of files.






share|improve this answer


















  • 1




    See unix.stackexchange.com/a/156010/116858
    – Kusalananda
    Sep 25 '17 at 18:04










  • The identify: unable to open image... error will be output by identify on its stderr, so won't be captured by $(...). as there won't be anything on stdout, $(...) will expand to an empty string, so it's like running find ... -exec echo '' ;
    – Stéphane Chazelas
    Sep 25 '17 at 19:43

















up vote
2
down vote













That's because echo doesn't know what is inside itself to expand it, only exec understand , in this case you should use in sh -c mode.



find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '' ;





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%2f394365%2ffind-current-filename-evaluates-to-empty-in-nested-command%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
    1
    down vote



    accepted










    Use:



    find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    Explanation



    The problem is with the way bash expands variables



    find * -type f -exec echo "$(identify -format '%w-%h' )" ;


    First bash expands what is in side $(...):



    find * -type f -exec echo 'identify: unable to open image `': No such file or directory...' ;


    At which point find will use the same exec statement for all commands with a rather useless argument. What you want to do is suppress the bash expansion for inside the finds exec. You can stop bash expanding things by placing them inside single quotes



    find * -type f -exec echo '$(identify -format %w-%h )' ;


    But here we lose expansion completely, we can inject it back by running the expression with sh -c



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h )"' ;


    Having within the shell script can also lead to some unexpected errors when dealing with whitespace or quotes or any character special to the shell in file names. To get around this you should move the as an argument to sh with:



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    See this question/answer for a more detailed explanation of this.



    Finally you can replace the * with . to let find find the files in the current directory by itself (and include hidden ones and not fail for filenames starting with -).



    Additionally, you can add the -x flag to sh to get it to print out what was it executed to help with debugging the command - this can be very noisy for a lot of files.






    share|improve this answer


















    • 1




      See unix.stackexchange.com/a/156010/116858
      – Kusalananda
      Sep 25 '17 at 18:04










    • The identify: unable to open image... error will be output by identify on its stderr, so won't be captured by $(...). as there won't be anything on stdout, $(...) will expand to an empty string, so it's like running find ... -exec echo '' ;
      – Stéphane Chazelas
      Sep 25 '17 at 19:43














    up vote
    1
    down vote



    accepted










    Use:



    find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    Explanation



    The problem is with the way bash expands variables



    find * -type f -exec echo "$(identify -format '%w-%h' )" ;


    First bash expands what is in side $(...):



    find * -type f -exec echo 'identify: unable to open image `': No such file or directory...' ;


    At which point find will use the same exec statement for all commands with a rather useless argument. What you want to do is suppress the bash expansion for inside the finds exec. You can stop bash expanding things by placing them inside single quotes



    find * -type f -exec echo '$(identify -format %w-%h )' ;


    But here we lose expansion completely, we can inject it back by running the expression with sh -c



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h )"' ;


    Having within the shell script can also lead to some unexpected errors when dealing with whitespace or quotes or any character special to the shell in file names. To get around this you should move the as an argument to sh with:



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    See this question/answer for a more detailed explanation of this.



    Finally you can replace the * with . to let find find the files in the current directory by itself (and include hidden ones and not fail for filenames starting with -).



    Additionally, you can add the -x flag to sh to get it to print out what was it executed to help with debugging the command - this can be very noisy for a lot of files.






    share|improve this answer


















    • 1




      See unix.stackexchange.com/a/156010/116858
      – Kusalananda
      Sep 25 '17 at 18:04










    • The identify: unable to open image... error will be output by identify on its stderr, so won't be captured by $(...). as there won't be anything on stdout, $(...) will expand to an empty string, so it's like running find ... -exec echo '' ;
      – Stéphane Chazelas
      Sep 25 '17 at 19:43












    up vote
    1
    down vote



    accepted







    up vote
    1
    down vote



    accepted






    Use:



    find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    Explanation



    The problem is with the way bash expands variables



    find * -type f -exec echo "$(identify -format '%w-%h' )" ;


    First bash expands what is in side $(...):



    find * -type f -exec echo 'identify: unable to open image `': No such file or directory...' ;


    At which point find will use the same exec statement for all commands with a rather useless argument. What you want to do is suppress the bash expansion for inside the finds exec. You can stop bash expanding things by placing them inside single quotes



    find * -type f -exec echo '$(identify -format %w-%h )' ;


    But here we lose expansion completely, we can inject it back by running the expression with sh -c



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h )"' ;


    Having within the shell script can also lead to some unexpected errors when dealing with whitespace or quotes or any character special to the shell in file names. To get around this you should move the as an argument to sh with:



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    See this question/answer for a more detailed explanation of this.



    Finally you can replace the * with . to let find find the files in the current directory by itself (and include hidden ones and not fail for filenames starting with -).



    Additionally, you can add the -x flag to sh to get it to print out what was it executed to help with debugging the command - this can be very noisy for a lot of files.






    share|improve this answer














    Use:



    find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    Explanation



    The problem is with the way bash expands variables



    find * -type f -exec echo "$(identify -format '%w-%h' )" ;


    First bash expands what is in side $(...):



    find * -type f -exec echo 'identify: unable to open image `': No such file or directory...' ;


    At which point find will use the same exec statement for all commands with a rather useless argument. What you want to do is suppress the bash expansion for inside the finds exec. You can stop bash expanding things by placing them inside single quotes



    find * -type f -exec echo '$(identify -format %w-%h )' ;


    But here we lose expansion completely, we can inject it back by running the expression with sh -c



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h )"' ;


    Having within the shell script can also lead to some unexpected errors when dealing with whitespace or quotes or any character special to the shell in file names. To get around this you should move the as an argument to sh with:



    find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh ;


    See this question/answer for a more detailed explanation of this.



    Finally you can replace the * with . to let find find the files in the current directory by itself (and include hidden ones and not fail for filenames starting with -).



    Additionally, you can add the -x flag to sh to get it to print out what was it executed to help with debugging the command - this can be very noisy for a lot of files.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 25 '17 at 19:47









    Stéphane Chazelas

    284k53523860




    284k53523860










    answered Sep 25 '17 at 17:44









    Michael Daffin

    2,6101517




    2,6101517







    • 1




      See unix.stackexchange.com/a/156010/116858
      – Kusalananda
      Sep 25 '17 at 18:04










    • The identify: unable to open image... error will be output by identify on its stderr, so won't be captured by $(...). as there won't be anything on stdout, $(...) will expand to an empty string, so it's like running find ... -exec echo '' ;
      – Stéphane Chazelas
      Sep 25 '17 at 19:43












    • 1




      See unix.stackexchange.com/a/156010/116858
      – Kusalananda
      Sep 25 '17 at 18:04










    • The identify: unable to open image... error will be output by identify on its stderr, so won't be captured by $(...). as there won't be anything on stdout, $(...) will expand to an empty string, so it's like running find ... -exec echo '' ;
      – Stéphane Chazelas
      Sep 25 '17 at 19:43







    1




    1




    See unix.stackexchange.com/a/156010/116858
    – Kusalananda
    Sep 25 '17 at 18:04




    See unix.stackexchange.com/a/156010/116858
    – Kusalananda
    Sep 25 '17 at 18:04












    The identify: unable to open image... error will be output by identify on its stderr, so won't be captured by $(...). as there won't be anything on stdout, $(...) will expand to an empty string, so it's like running find ... -exec echo '' ;
    – Stéphane Chazelas
    Sep 25 '17 at 19:43




    The identify: unable to open image... error will be output by identify on its stderr, so won't be captured by $(...). as there won't be anything on stdout, $(...) will expand to an empty string, so it's like running find ... -exec echo '' ;
    – Stéphane Chazelas
    Sep 25 '17 at 19:43












    up vote
    2
    down vote













    That's because echo doesn't know what is inside itself to expand it, only exec understand , in this case you should use in sh -c mode.



    find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '' ;





    share|improve this answer


























      up vote
      2
      down vote













      That's because echo doesn't know what is inside itself to expand it, only exec understand , in this case you should use in sh -c mode.



      find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '' ;





      share|improve this answer
























        up vote
        2
        down vote










        up vote
        2
        down vote









        That's because echo doesn't know what is inside itself to expand it, only exec understand , in this case you should use in sh -c mode.



        find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '' ;





        share|improve this answer














        That's because echo doesn't know what is inside itself to expand it, only exec understand , in this case you should use in sh -c mode.



        find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '' ;






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Sep 25 '17 at 17:53









        Kusalananda

        106k14209327




        106k14209327










        answered Sep 25 '17 at 17:41









        αғsнιη

        15.7k92563




        15.7k92563



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f394365%2ffind-current-filename-evaluates-to-empty-in-nested-command%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