3

I am playing around with -exec flag of find command. I am trying to use the flag to print the extension name of files, using a fairly new Linux distribution release.

Starting simple, this works:

find . -type f -exec echo {} \;

An attempt to use convenient Bash string feature fails:

find . -type f -exec echo "${{}##*.}" \; (bad substitution)

So what should be the correct way to do it?

  • Although it won't help in this case, read about the -printf option in the find man page -- it can tell you a lot of information about the files found. – glenn jackman Jan 13 '15 at 15:03
3

If you want to use shell parameter expansion then run some shell with exec:

find . -type f -exec sh -c 'echo "${0##*.}"' {} \;
  • 1
    I get bad substitution with this still, but it works if you use bash instead of sh – Captain Lepton Jan 13 '15 at 15:05
  • It is possible if your sh is a link to the shell which doesn't support parameter expansion. bash is good choice. – jimmij Jan 13 '15 at 15:07
  • Correct jimmij, just pointing out that not all sh are equal. Does exec create a new shell child process each time? – Captain Lepton Jan 13 '15 at 15:10
  • @CaptainLepton Yes, you can find out with find . -type f -exec sh -c 'echo "$$"' {} \; – jimmij Jan 13 '15 at 15:13
2
 find . -type f | while read file; do echo "${file##*.}"; done

Has the advantage of bypassing all that tricky exec syntax that no one can ever remember.

Also has the advantage of only creating one child process, instead of creating and destroying one for every found file. This is considerably faster than jimmij's version using exec

# Preparation - 1000 files
for i in {1..1000}; do touch $i.$i; done

>time find . -type f -exec sh -c 'echo "${0##*.}"' {} \;
real    0m21.906s
user    0m6.013s
sys     0m12.304s


>time find . -type f | while read file; do echo "${file##*.}"; done
real    0m0.219s
user    0m0.125s
sys     0m0.087s

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.