Jawaban:
Di GNU findAnda dapat menggunakan -printfparameter untuk itu, misalnya:
find /dir1 -type f -printf "%f\n"
-omemiliki prioritas lebih rendah daripada yang tersirat -a, sehingga Anda akan sering ingin mengelompokkan -oargumen Anda )
Jika temuan Anda tidak memiliki opsi -printf, Anda juga dapat menggunakan nama samaran:
find ./dir1 -type f -exec basename {} \;
... {} ';'
Gunakan -execdiryang secara otomatis menyimpan file saat ini {}, misalnya:
find . -type f -execdir echo '{}' ';'
Anda juga dapat menggunakan $PWDsebagai gantinya .(pada beberapa sistem itu tidak akan menghasilkan titik ekstra di depan).
Jika Anda masih mendapat titik tambahan, Anda juga dapat menjalankan:
find . -type f -execdir basename '{}' ';'
-execdir utility [argument ...] ;The
-execdirutama adalah identik dengan-execprimer dengan pengecualian bahwa utilitas akan dieksekusi dari direktori yang memegang file saat ini .
Saat digunakan +sebagai pengganti ;, kemudian {}diganti dengan sebanyak mungkin nama path untuk setiap pemanggilan utilitas. Dengan kata lain, itu akan mencetak semua nama file dalam satu baris.
./filenamebukan filename. Tergantung pada kebutuhan Anda, mungkin atau mungkin tidak baik-baik saja.
$PWDbukan ..
Jika Anda menggunakan GNU find
find . -type f -printf "%f\n"
Atau Anda dapat menggunakan bahasa pemrograman seperti Ruby (1.9+)
$ ruby -e 'Dir["**/*"].each{|x| puts File.basename(x)}'
Jika Anda suka solusi bash (setidaknya 4)
shopt -s globstar
for file in **; do echo ${file##*/}; done
Jika Anda ingin menjalankan beberapa tindakan terhadap nama file saja, menggunakan basenamebisa jadi sulit.
Sebagai contoh ini:
find ~/clang+llvm-3.3/bin/ -type f -exec echo basename {} \;
hanya akan mengulang nama dasar /my/found/path. Bukan yang kita inginkan jika kita ingin mengeksekusi pada nama file.
Tetapi Anda bisa kemudian xargsoutput. misalnya untuk membunuh file dalam direktori berdasarkan nama di direktori lain:
cd dirIwantToRMin;
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \; | xargs rm
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \;
-execdan -execdirlambat, xargsadalah raja.
$ alias f='time find /Applications -name "*.app" -type d -maxdepth 5'; \
f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l; \
f -print0 | xargs -0 basename | wc -l
139
0m01.17s real 0m00.20s user 0m00.93s system
139
0m01.16s real 0m00.20s user 0m00.92s system
139
0m01.05s real 0m00.17s user 0m00.85s system
139
0m00.93s real 0m00.17s user 0m00.85s system
139
0m00.88s real 0m00.12s user 0m00.75s system
xargsParalelisme juga membantu.
Lucunya saya tidak bisa menjelaskan kasus terakhir xargstanpa -n1. Ini memberikan hasil yang benar dan tercepat¯\_(ツ)_/¯
( basenamehanya membutuhkan 1 argumen jalan tetapi xargsakan mengirim semuanya (sebenarnya 5000) tanpa -n1. Tidak berfungsi di linux dan openbsd, hanya macOS ...)
Beberapa angka yang lebih besar dari sistem linux untuk melihat bagaimana -execdirmembantu, tetapi masih jauh lebih lambat daripada paralel xargs:
$ alias f='time find /usr/ -maxdepth 5 -type d'
$ f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l
2358
3.63s real 0.10s user 0.41s system
2358
1.53s real 0.05s user 0.31s system
2358
1.30s real 0.03s user 0.21s system
2358
0.41s real 0.03s user 0.25s system
findadalah -execdiryang menjadi tercepat karena menciptakan proses baru adalah operasi yang relatif mahal.
Jujur basenamedan dirnamesolusinya lebih mudah, tetapi Anda juga dapat memeriksanya:
find . -type f | grep -oP "[^/]*$"
atau
find . -type f | rev | cut -d '/' -f1 | rev
atau
find . -type f | sed "s/.*\///"
Seperti yang telah ditunjukkan orang lain, Anda dapat menggabungkan finddan basename, tetapi secara default basenameprogram hanya akan beroperasi pada satu jalur pada satu waktu, sehingga yang dapat dieksekusi harus diluncurkan satu kali untuk setiap jalur (menggunakan salah satu find ... -execatau find ... | xargs -n 1), yang mungkin berpotensi lambat.
Jika Anda menggunakan -aopsi aktif basename, maka ia dapat menerima beberapa nama file dalam satu pemanggilan tunggal, yang berarti bahwa Anda kemudian dapat menggunakan xargstanpa -n 1, untuk mengelompokkan jalur bersama menjadi jumlah pemanggilan yang jauh lebih kecil basename, yang seharusnya lebih efisien.
Contoh:
find /dir1 -type f -print0 | xargs -0 basename -a
Di sini saya telah menyertakan -print0dan -0(yang harus digunakan bersama-sama), untuk mengatasi spasi putih di dalam nama file dan direktori.
Berikut ini adalah perbandingan waktu, antara versi xargs basename -adan xargs -n1 basename. (Demi perbandingan suka-dengan-suka, timing yang dilaporkan di sini adalah setelah dummy run awal, sehingga keduanya dilakukan setelah file metadata telah disalin ke cache I / O.) Saya telah mengirim output ke cksumdalam kedua kasus, hanya untuk menunjukkan bahwa output tidak tergantung pada metode yang digunakan.
$ 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
Seperti yang Anda lihat, ini sebenarnya jauh lebih cepat untuk menghindari peluncuran basenamesetiap saat.
basenameakan menerima beberapa nama file tanpa memerlukan argumen baris perintah tambahan. Penggunaan di -asini adalah di Linux. ( basename --versionMemberitahu saya basename (GNU coreutils) 8.28.)