Find and basename not playing nicely

前端 未结 4 1688
無奈伤痛
無奈伤痛 2020-12-13 05:55

I want to echo out the filename portion of a find on the linux commandline. I\'ve tried to use the following:

find www/*.html -type f -exec sh -c \"echo $(b         


        
4条回答
  •  一向
    一向 (楼主)
    2020-12-13 06:26

    I had to accomplish something similar, and found following the practices mentioned for avoiding looping over find's output and using find with sh sidestepped these problems with {} and -printfentirely.

    You can try it like this:

    find www/*.html -type f -exec sh -c 'echo $(basename $1)' find-sh {} \;
    

    The summary is "Don't reference {} directly inside of a sh -c but instead pass it to sh -c as an argument, then you can reference it with a number variable inside of sh -c" the find-sh is just there as a dummy to take up the $0, there is more utility in doing it that way and using {} for $1.

    I'm assuming the use of echo is really to simplify the concept and test function. There are easier ways to simply echo as others have mentioned, But an ideal use case for this scenario might be using cp, mv, or any more complex commands where you want to reference the found file names more than once in the command and you need to get rid of the path, eg. when you have to specify filename in both source and destination or if you are renaming things.

    So for instance, if you wanted to copy only the html documents to your public_html directory (Why? because Example!) then you could:

     find www/*.html -type f -exec sh -c 'cp /var/www/$(basename $1) /home/me/public_html/$(basename $1)' find-sh {} \;
    

    Over on unix stackexchange, user wildcard's answer on looping with find goes into some great gems on usage of -exec and sh -c. (You can find it here: https://unix.stackexchange.com/questions/321697/why-is-looping-over-finds-output-bad-practice)

提交回复
热议问题