GNU/Linux >> Belajar Linux >  >> Linux

Gunakan perintah find tetapi kecualikan file dalam dua direktori

Inilah salah satu cara Anda dapat melakukannya...

find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"

bagi saya, solusi ini tidak berfungsi pada perintah exec dengan find, tidak begitu tahu mengapa, jadi solusi saya adalah

find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;

Penjelasan: sama seperti sampson-chen satu dengan tambahan

-Pangkas - abaikan jalur pemrosesan ...

-o - Lalu jika tidak cocok, cetak hasilnya, (pangkas direktori dan cetak hasil yang tersisa)

18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;

gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3:    0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4:    0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5:    0.0% -- replaced with ./e/5.gz
./e/a:    0.0% -- replaced with ./e/a.gz
./e/b:    0.0% -- replaced with ./e/b.gz

Inilah cara Anda dapat menentukannya dengan find :

find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"

Penjelasan:

  • find . - Mulai temukan dari direktori kerja saat ini (secara default secara rekursif)
  • -type f - Tentukan ke find bahwa Anda hanya menginginkan file dalam hasil
  • -name "*_peaks.bed" - Cari file dengan nama berakhiran _peaks.bed
  • ! -path "./tmp/*" - Kecualikan semua hasil yang jalurnya dimulai dengan ./tmp/
  • ! -path "./scripts/*" - Kecualikan juga semua hasil yang jalurnya dimulai dengan ./scripts/

Menguji Solusi:

$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"

./d/4
./c/3
./e/a
./e/b
./e/5

Anda cukup dekat, -name opsi hanya mempertimbangkan nama dasar, sedangkan -path mempertimbangkan seluruh jalur =)


Gunakan

find \( -path "./tmp" -o -path "./scripts" \) -prune -o  -name "*_peaks.bed" -print

atau

find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o  -name "*_peaks.bed"

atau

find \( -path "./tmp" -path "./scripts" \) ! -prune -o  -name "*_peaks.bed"

Urutan itu penting. Ini mengevaluasi dari kiri ke kanan. Selalu mulai dengan pengecualian jalur.

Penjelasan

Jangan gunakan -not (atau ! ) untuk mengecualikan seluruh direktori. Gunakan -prune .Seperti yang dijelaskan dalam manual:

−prune    The primary shall always evaluate as  true;  it
          shall  cause  find  not  to descend the current
          pathname if it is a directory.  If  the  −depth
          primary  is specified, the −prune primary shall
          have no effect.

dan di GNU temukan manual:

-path pattern
              [...]
              To ignore  a  whole
              directory  tree,  use  -prune rather than checking
              every file in the tree.

Memang kalau pakai -not -path "./pathname" ,find akan mengevaluasi ekspresi untuk setiap node di bawah "./pathname" .

ekspresi find hanyalah evaluasi kondisi.

  • \( \) - operasi grup (Anda dapat menggunakan -path "./tmp" -prune -o -path "./scripts" -prune -o , tetapi lebih bertele-tele).
  • -path "./script" -prune - jika -path mengembalikan true dan merupakan direktori, mengembalikan true untuk direktori itu dan tidak turun ke dalamnya.
  • -path "./script" ! -prune - dievaluasi sebagai (-path "./script") AND (! -prune) . Itu mengembalikan "selalu benar" dari pangkas menjadi selalu salah. Ini menghindari pencetakan "./script" sebagai pasangan.
  • -path "./script" -prune -false - sejak -prune selalu mengembalikan true, Anda dapat mengikutinya dengan -false untuk melakukan hal yang sama dari ! .
  • -o - ATAU operator. Jika tidak ada operator yang ditentukan di antara dua ekspresi, defaultnya adalah operator AND.

Oleh karena itu, \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print diperluas ke:

[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )

Cetak penting di sini karena tanpa itu diperluas ke:

{ [ (-path "./tmp" OR -path "./script" )  AND -prune ]  OR (-name "*_peaks.bed" ) } AND print

-print ditambahkan oleh find - itulah mengapa sebagian besar waktu, Anda tidak perlu menambahkannya dalam ekspresi Anda. Dan sejak -prune mengembalikan true, itu akan mencetak "./script" dan "./tmp".

Tidak perlu di yang lain karena kami mengganti -prune untuk selalu mengembalikan false.

Petunjuk:Anda dapat menggunakan find -D opt expr 2>&1 1>/dev/null untuk melihat bagaimana itu dioptimalkan dan diperluas,
find -D search expr 2>&1 1>/dev/null untuk melihat jalur mana yang diperiksa.


Linux
  1. Temukan file dan direktori di Linux dengan perintah find

  2. Cara Menggunakan Perintah Grep untuk Menemukan Teks di File

  3. Salin file &direktori di Linux

  1. Kecualikan Daftar Direktori Dari Unix Temukan Perintah?

  2. Cara Menggunakan Perintah find Linux untuk Menemukan File

  3. Cara mengecualikan direktori di find . memerintah

  1. Cara Mengetahui Direktori dan File Teratas (Ruang Disk) di Linux

  2. Bagaimana menemukan / mendaftar semua file unik di dua direktori?

  3. Bagaimana cara menggunakan perintah find untuk menghapus file yang cocok dengan pola?