How to only get file name with Linux 'find'?

后端 未结 10 1359
故里飘歌
故里飘歌 2020-11-28 18:19

I\'m using find to all files in directory, so I get a list of paths. However, I need only file names. i.e. I get ./dir1/dir2/file.txt and I want to get fi

10条回答
  •  春和景丽
    2020-11-28 18:59

    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.

    Example:

    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.

提交回复
热议问题