Pada dasarnya ada 2 metode yang dapat Anda gunakan untuk melakukan ini. Satu akan mengurai string sedangkan yang lain akan beroperasi pada setiap file. Parsing string menggunakan alat seperti grep
, sed
, atau awk
jelas akan lebih cepat tapi di sini adalah contoh yang menunjukkan keduanya, serta bagaimana Anda bisa "profil" 2 metode.
Contoh data
Untuk contoh di bawah ini kami akan menggunakan data berikut
$ touch dir{1..3}/dir{100..112}/file{1..5}
$ touch dir{1..3}/dir{100..112}/nile{1..5}
$ touch dir{1..3}/dir{100..112}/knife{1..5}
Hapus beberapa *f*
file dari dir1/*
:
$ rm dir1/dir10{0..2}/*f*
Approach # 1 - Parsing via string
Di sini kita akan menggunakan alat-alat berikut, find
, grep
, dan sort
.
$ find . -type f -name '*f*' | grep -o "\(.*\)/" | sort -u | head -5
./dir1/dir103/
./dir1/dir104/
./dir1/dir105/
./dir1/dir106/
./dir1/dir107/
Approach # 2 - Parsing menggunakan file
Rantai alat yang sama seperti sebelumnya, kecuali kali ini kami akan menggunakan dirname
bukan grep
.
$ find . -type f -name '*f*' -exec dirname {} \; | sort -u | head -5
./dir1/dir103
./dir1/dir104
./dir1/dir105
./dir1/dir106
./dir1/dir107
CATATAN: Contoh di atas hanya digunakan head -5
untuk membatasi jumlah output yang kita hadapi untuk contoh-contoh ini. Biasanya akan dihapus untuk mendapatkan daftar lengkap Anda!
Membandingkan hasilnya
Kita dapat menggunakan time
untuk melihat 2 pendekatan.
dirname
real 0m0.372s
user 0m0.028s
sys 0m0.106s
grep
real 0m0.012s
user 0m0.009s
sys 0m0.007s
Jadi selalu yang terbaik untuk berurusan dengan string jika memungkinkan.
Metode penguraian string alternatif
grep & PCRE
$ find . -type f -name '*f*' | grep -oP '^.*(?=/)' | sort -u
sed
$ find . -type f -name '*f*' | sed 's#/[^/]*$##' | sort -u
awk
$ find . -type f -name '*f*' | awk -F'/[^/]*$' '{print $1}' | sort -u
uniq
ke dalam campuran sangat membantu dengan menghapus garis berulang yang sudah tepat bersebelahan.find . -type f -name '*f*' -printf '%h\0' | uniq -z | sort -zu | tr '\0' '\n'
. Atau jika alat Anda sedikit lebih tua, maka uniq mungkin tidak memiliki opsi -z.find . -type f -name '*f*' -printf '%h\n' | uniq | sort -u