2

I have been trying to print out the base file names using find in Unix. To simply print out the file names the command I have been using is this

find . -type f -name \*.out -print

It prints out the full path qualified path names. But I want the base file names only. That is why I have been trying the following command

find . -type f -name \*.out -exec basename {}

But it errors out and displays

find: incomplete statement

Please help me through.

0

3 Answers 3

8

You missing ; character to terminate primary expression (See POSIX find):

find . -type f -name \*.out -exec basename {} ';'

The reason you must escape, or quote ; because it's your shell list separator. You must make your shell treat it literally. \;, ';' or ";" all work well.

But this solution will call basename for each file found, make it slow. If file names don't contain newline, you can:

find . -type f -name '*.out' | sed -e 's#.*/##'

If you have GNU coreutils version >= 8.16, or you are on OSX, you can use basename -a:

find . -type f -name '*.out' -exec basename -a -- {} +
4
  • Not only OSX find supports -a. GNU find does it as well.
    – jlliagre
    Nov 21, 2014 at 8:46
  • @jlliagre: I guess you mean basename instead of find. And at least in Debian Wheezy, (GNU coreutils) 8.13, it doesn't.
    – cuonglm
    Nov 21, 2014 at 8:50
  • That was basename indeed, not find. That looks to be a recent addition as this option is supported at least with GNU coreutils 8.20.
    – jlliagre
    Nov 21, 2014 at 8:57
  • @jlliagre: The change was made in version 8.16, I added it to my answer.
    – cuonglm
    Nov 21, 2014 at 9:34
5

Your command is missing a semicolon at the end, to terminate the -exec:

find . -type f -name \*.out -exec basename {} \;

But that command will run quite slowly because it forks an external process and calls basename for each and every match. If your find supports the -printf option, you might want to use that instead:

find . -type f -name \*.out -printf '%f\n'
2
  • That sounds good and works pretty well but why is that ; needed after all and why do we need to escape it ?
    – recmach
    Nov 21, 2014 at 7:45
  • 2
    For why it's needed, that's clearly documented in the manpage. Please read it. It's how find knows where your command ends. For why it needs to be escaped, it's a shall metacharacter.
    – Celada
    Nov 21, 2014 at 7:48
2

you left \;

 find . -type f -name \*.out -exec basename {} \;

If your file paths don't contain newline characters, you can also use awk:

find . -type f -name \*.out -print | awk -F "/" '{print $NF}'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .