Daftar semua direktori yang TIDAK memiliki file dengan nama file yang diberikan di dalamnya

11

Bagaimana saya masuk ke daftar semua direktori yang tidak memiliki file dengan nama file yang diberikan di dalamnya? misal diberi pohon ini

/
  /a
     README
     file001
     file002
  /b
     README
     file001
  /c
     file003

Saya ingin daftar direktori yang tidak memiliki nama file README, dalam hal ini akan menjadi direktori /c. Bagaimana saya melakukannya? Saya tidak bisa memikirkan sintaks menggunakan mis find.

Renan
sumber
Sayang sekali Anda tidak mencari: askubuntu.com/questions/196960/…
slm
Saya tidak memikirkan kata kunci yang tepat saat mencari, mungkin.
Renan
2
Aku hanya menangkapmu. Saya telah ke sana berkali-kali di mana saya tidak bisa memikirkan kata yang tepat untuk mencari sesuatu 8-).
slm
terkait: askubuntu.com/questions/196960/…
Ciro Santilli 冠状 病毒 审查 六四 事件 事件 法轮功

Jawaban:

5

Dengan asumsi findimplementasi seperti GNU findyang menerima {}tertanam dalam argumen ke -exec:

$ find . -type d \! -exec test -e '{}/README' \; -print

Contoh

Di sini direktori 1/1 hingga 5/5 memiliki README, direktori lainnya kosong.

$ tree 
.
|-- 1
|   `-- 1
|       `-- README
|-- 10
|   `-- 10
|-- 2
|   `-- 2
|       `-- README
|-- 3
|   `-- 3
|       `-- README
|-- 4
|   `-- 4
|       `-- README
|-- 5
|   `-- 5
|       `-- README
|-- 6
|   `-- 6
|-- 7
|   `-- 7
|-- 8
|   `-- 8
`-- 9
    `-- 9

Sekarang ketika kita menjalankan versi findperintah ini:

$ find . -type d \! -exec test -e '{}/README' \; -print
.
./10
./10/10
./7
./7/7
./9
./9/9
./6
./6/6
./5
./8
./8/8
./4
./1
./3
./2

Referensi

slm
sumber
Cara memodifikasi perintah untuk mencari sub direktori yang tidak memiliki ekstensi file tertentu (katakan * .txt). Memodifikasi README dengan * .txt tampaknya tidak berfungsi
WanderingMind
@WanderingMind - jika Anda memiliki pertanyaan baru silakan tanyakan sebagai yang baru di situs ;-)
slm
3

Anda dapat menggunakan -execopsi finduntuk memeriksa file, dan kemudian mencetak semua hasil yang gagal diperiksa.

find /path/to/base -mindepth 1 -maxdepth 1 -type d -exec test -e {}/README \; -o -print
Patrick
sumber
3

Tidak perlu find. Cukup gunakan shell:

for d in */; do [ -f "$d"README ] || printf '%s\n' "$d"; done
c/

Jika Anda membutuhkannya untuk rekursif, Anda dapat menggunakan (untuk bash, zshdapat melakukan ini secara default, gunakan set -o globstardalam ksh93):

shopt -s globstar
for d in **/; do [ -f "$d"README ] || printf '%s\n' "$d"; done

(perhatikan bahwa file-file dot dikecualikan secara default).

terdon
sumber
2

Dengan zshdan kualifikasi glob ( estring ):

print -rl -- *(/e_'[[ ! -f $REPLY/README ]]'_)

atau

print -rl -- *(/^e_'[[ -f $REPLY/README ]]'_)

tambahkan Duntuk memasukkan direktori tersembunyi:

print -rl -- *(D/e_'[[ ! -f $REPLY/README ]]'_)

/hanya memilih direktori dan e_'[[ ! -f $REPLY/README ]]'_selanjutnya hanya memilih nama direktori yang kode shellnya di antara tanda kutip kembali true, yaitu untuk setiap nama direktori ( $REPLY) tempat glob *(/)berkembang, ia menjalankan [[ ! -f $REPLY/README ]]dan menyimpan nama direktori jika hasilnya true.
Bentuk kedua ^e_'.....'_menggunakan kualifikasi glob yang sama, dinegasikan (tapi kali ini ekspresi kondisional tidak dinegasikan:) [[ -f $REPLY/README ]].


Di atas hanya akan mengembalikan nama direktori di direktori saat ini.
Jika Anda ingin mencari secara rekursif (lagi, untuk memasukkan direktori tersembunyi tambahkan Dkualifikasi):

print -rl ./**/*(/e_'[[ ! -f $REPLY/README ]]'_)
don_crissti
sumber
2

Portable, Anda bisa melakukan:

find . -type d -exec sh -c '
  for dir do
    [ -f "$dir/README" ] || printf "%s\n" "$dir"
  done' sh '{}' +

[ -f file ]menguji apakah file tersebut ada dan dikonfirmasi sebagai file biasa (setelah resolusi symlink).

Jika Anda ingin menguji bahwa itu hanya ada (sebagai entri dalam direktori itu), terlepas dari jenisnya, Anda perlu [ -e file ] || [ -L file ]:, meskipun perlu diketahui bahwa Anda memerlukan izin pencarian ke direktori untuk melakukan tes tersebut. Anda mungkin ingin menambahkan beberapa [ -x "$dir" ]tes ke akun untuk kasus-kasus seperti:

find . -type d -exec sh -c '
  for dir do
    if [ -x "$dir" ]; then
      [ -f "$dir/README" ] || printf "%s\n" "$dir"
    else
      printf >&2 "Cannot tell for \"%s\"\n" "$dir"
    fi
  done' sh '{}' +

Atau untuk menghindari kondisi balapan, dengan zsh:

find . -type d -exec zsh -c '
  zmodload zsh/system
  for dir do
    ERRNO=0
    if [ ! -f "$dir/README" ]; then
      if [ "$errnos[ERRNO]" = ENOENT ]; then
        printf "%s\n" "$dir"
      else
        syserror -p "ERROR: $dir/README: "
      fi
    fi
  done' zsh '{}' +

Lihat juga Bagaimana saya tahu jika file biasa tidak ada di Bash? pada SO.

Stéphane Chazelas
sumber