Linux find all files only

How to only get file name with Linux ‘find’?

In GNU find you can use -printf parameter for that, e.g.:

find /dir1 -type f -printf "%f\n" 

@Urchin No reason it shouldn’t so long as you have correct logic (i.e. -o has lower precedence than implied -a , so you will often want to group your -o arguments)

I don’t think this is the right answer. find -printf «%f\n» -exec echo <> \; reveals that the original filename is passed forward

If your find doesn’t have a -printf option you can also use basename:

find ./dir1 -type f -exec basename <> \; 

Use -execdir which automatically holds the current file in <> , for example:

find . -type f -execdir echo '<>' ';' 

You can also use $PWD instead of . (on some systems it won’t produce an extra dot in the front).

If you still got an extra dot, alternatively you can run:

find . -type f -execdir basename '<>' ';' 

-execdir utility [argument . ] ;

The -execdir primary is identical to the -exec primary with the exception that utility will be executed from the directory that holds the current file.

When used + instead of ; , then <> is replaced with as many pathnames as possible for each invocation of utility. In other words, it’ll print all filenames in one line.

If you are using GNU find

Or you can use a programming language such as Ruby(1.9+)

If you fancy a bash (at least 4) solution

shopt -s globstar for file in **; do echo $; done 

If you want to run some action against the filename only, using basename can be tough.

find ~/clang+llvm-3.3/bin/ -type f -exec echo basename <> \; 

will just echo basename /my/found/path . Not what we want if we want to execute on the filename.

Читайте также:  Как сделать сервер с линуксом

But you can then xargs the output. for example to kill the files in a dir based on names in another dir:

cd dirIwantToRMin; find ~/clang+llvm-3.3/bin/ -type f -exec basename <> \; | xargs rm 
find /dir1 -type f -exec basename <> \; 

As others have pointed out, you can combine find and basename , but by default the basename program will only operate on one path at a time, so the executable will have to be launched once for each path (using either find . -exec or find . | xargs -n 1 ), which may potentially be slow.

If you use the -a option on basename , then it can accept multiple filenames in a single invocation, which means that you can then use xargs without the -n 1 , to group the paths together into a far smaller number of invocations of basename , which should be more efficient.

find /dir1 -type f -print0 | xargs -0 basename -a 

Here I’ve included the -print0 and -0 (which should be used together), in order to cope with any whitespace inside the names of files and directories.

Here is a timing comparison, between the xargs basename -a and xargs -n1 basename versions. (For sake of a like-with-like comparison, the timings reported here are after an initial dummy run, so that they are both done after the file metadata has already been copied to I/O cache.) I have piped the output to cksum in both cases, just to demonstrate that the output is independent of the method used.

$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 basename -a | cksum' 2532163462 546663 real 0m0.063s user 0m0.058s sys 0m0.040s $ time sh -c 'find /usr/lib -type f -print0 | xargs -0 -n 1 basename | cksum' 2532163462 546663 real 0m14.504s user 0m12.474s sys 0m3.109s 

As you can see, it really is substantially faster to avoid launching basename every time.

Читайте также:  Расшарить папку linux mac

Источник

Оцените статью
Adblock
detector