ค้นหาไดเรกทอรีที่ไม่มีไดเรกทอรีย่อย


10

ฉันกำลังเขียนสคริปต์คือ ksh จำเป็นต้องค้นหาชื่อไดเรกทอรีทั้งหมดภายใต้ไดเรกทอรีปัจจุบันซึ่งมีเฉพาะไฟล์เท่านั้นไม่ใช่ไดเรกทอรีย่อย

ฉันรู้ว่าฉันสามารถใช้ls -alRและแยกวิเคราะห์เอาต์พุตแบบซ้ำ ๆ สำหรับตัวอักษรตัวแรกในฟิลด์แรก ( dสำหรับไดเรกทอรี) ฉันคิดว่าawkเป็นวิธีที่ดีที่สุดในการแยกวิเคราะห์และค้นหา

ตัวอย่างเช่นls -alเอาต์พุตแบบง่ายในไดเร็กทอรีปัจจุบัน:

   drwxr-xr-x  22 af      staff    748 18 Mar 22:21 .
   drwxr-xr-x   5 root    admin    170 17 Mar 18:03 ..
   -rw-------   1 af      staff      3 17 Mar 16:37 .CFUserTextEncoding
   drwxr-xr-x   5 af      staff    170 17 Mar 17:12 Public
   drwxr-xr-x   9 af      staff    306 18 Mar 17:40 Sites
   -rw-------   1 af      staff      3 17 Mar 16:37 textd
   

มี 2 ไดเรกทอรีในการส่งออกนี้คือ: และPublic SitesไดเรกทอรีPublicไม่ได้มีไดเรกทอรีย่อย แต่Sitesไม่ มี 3 Sitesไดเรกทอรีย่อยในเป็น ดังนั้นฉันจึงต้องสะท้อนเฉพาะไดเรกทอรีที่ไม่มีไดเรกทอรีในพวกเขา Sitesในกรณีของฉันนี้เป็นเพียง

คำตอบ:


1

คุณไม่จำเป็นต้องใช้awkเลย ใช้การทดสอบในตัวที่kshให้บางสิ่งเช่นนี้:

#!/bin/ksh

for NAME in *
do
    FOUND=no
    if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
    then
        for SUBNAME in $NAME/*
        do
            if [[ -d $SUBNAME ]]
            then
                FOUND=yes
                break
            fi
        done
        if [[ $FOUND == no ]]
        then
            echo Found only files in $NAME
        fi
    fi
done

สคริปต์ตัวเล็ก ๆ นั้นจะมีลักษณะอยู่ในไดเรกทอรีทั้งหมดในไดเรกทอรีปัจจุบันและบอกคุณว่ามีเพียงไฟล์เท่านั้นไม่มีไดเรกทอรีย่อย


14

หากคุณสามารถใช้งานได้findและหากคุณกำลังทำงานกับ "ระบบไฟล์ Unix ปกติ" (นั่นคือตามที่กำหนดไว้ในfind (1)ภายใต้คำอธิบายตัวเลือก-noleaf ) คุณสามารถใช้คำสั่งต่อไปนี้:

find . -type d -links 2

แต่ละไดเรกทอรีมีอย่างน้อย 2 ชื่อ (ฮาร์ดลิงก์): .และชื่อ หากมีไดเร็กทอรีย่อยจะมีการ..ชี้ไปที่ไดเร็กทอรีพาเรนต์ดังนั้นไดเร็กทอรีที่มีไดเร็กทอรีย่อย N จะมีฮาร์ดลิงก์นับเท่ากับ N + 2 ดังนั้นการค้นหาไดเรกทอรีที่มีฮาร์ดลิงก์จะนับเท่ากับ 2 เราจึงค้นหาไดเรกทอรีที่มีไดเรกทอรีย่อย N = 0

ดังนั้นหากคุณสามารถใช้งานfindได้นี่เป็นวิธีที่เร็วที่สุดและเหนือกว่าการใช้ in-shell ลูปในเนื้อหาไดเรกทอรีที่stat()สมาชิกแต่ละคนใช้


ดูเหมือนจะไม่สามารถใช้งานได้หากไดเรกทอรีมีไฟล์ใด ๆ
user394

1
มันไม่เกี่ยวกับรายการต่าง ๆ ในรายการไดเรกทอรีมันเป็นเรื่องเกี่ยวกับฮาร์ดลิงก์ที่อ้างถึง inode ของไดเรกทอรี ตัวอย่างเช่นถ้า/some/directoryมี inode # 12345678 ถ้ามันไม่มีไดเรกทอรีย่อยจะมีการเชื่อมโยงว่า 2 ยากที่จะ inode ว่าและ/some/directory/. /some/directoryมันทำงานได้หรือไม่มีไฟล์ใด ๆ ในไดเรกทอรี
telcoM

น่ากล่าวถึงว่า BTRFS ไม่ใช่ "ระบบไฟล์ Unix ปกติ" ในแง่นี้: ไดเรกทอรีมีจำนวนลิงค์ 1 เสมอขออภัย ( แต่.และfoo/..จะมีหมายเลขไอโหนดเดียวกัน.)
ปีเตอร์ Cordes

3

*/ตรงกับไดเรกทอรีย่อยของไดเรกทอรีปัจจุบัน ซึ่งรวมถึงลิงก์สัญลักษณ์ไปยังไดเรกทอรีซึ่งคุณอาจต้องการหรือไม่ต้องการ

ใน ksh93 การเพิ่ม~(N)ที่จุดเริ่มต้นของรูปแบบทำให้ขยายไปยังรายการว่างหากไม่มีการจับคู่ หากไม่มีสิ่งนี้ลวดลายจะยังคงไม่เปลี่ยนแปลงหากไม่มีการจับคู่

ฟังก์ชัน ksh93 ต่อไปนี้แสดงรายการไดเรกทอรีย่อยของไดเรกทอรีปัจจุบันที่ไม่มีไดเรกทอรีย่อยหรือลิงค์ไปยังไดเรกทอรี

list_leaf_directories () {
  local FIGNORE='.?(.)'        # don't ignore dot files
  local d
  for d in */; do
    [[ -L $d ]] || continue;   # skip symbolic links
    set -- ~(N)"$d"/*/
    if ((!$#)); then echo "$d"; fi
  done
done

0

ถ้าฉันไม่เข้าใจคุณผิดคุณก็แค่ต้องการค้นหาไฟล์ในไดเรกทอรีไม่ใช่ไดเรกทอรีย่อย หากนี่คือความตั้งใจของคุณนี่คือทางออก

find . -type f

หากคุณต้องการหาไฟล์อื่นนอกเหนือจากไฟล์ปกติ (เช่นไฟล์อุปกรณ์บล็อกไฟล์อุปกรณ์อักขระ ฯลฯ ) จากนั้นให้ดูfindคำสั่งman page และค้นหาคีย์เวิร์ดtypeในหน้านั้น คุณจะเห็นประเภทไฟล์ต่าง ๆ รวมถึงไฟล์และไดเรกทอรีปกติเป็นต้น

หวังว่านี่คือสิ่งที่คุณกำลังมองหา


ไม่นั่นไม่ใช่คำถามเลย มันชัดเจนพอสมควรเมื่อคุณ s / catalog / directory / g Nat Kup กำลังค้นหาไดเรกทอรีที่ไม่มีไดเรกทอรีย่อย
Gilles 'หยุดความชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.