ฉันต้องการเชลล์สคริปต์ของฉันเพื่อเยี่ยมชมไดเรกทอรีย่อยทั้งหมดในไดเรกทอรีหลัก ทำบางสิ่งในไดเรกทอรีส่งออกไปยังไฟล์สปูลและย้ายไปยังไดเรกทอรีถัดไป พิจารณา Dir หลัก = / tmp Sub Dir = ABCD (ไดเรกทอรีย่อยสี่แห่ง)
ฉันต้องการเชลล์สคริปต์ของฉันเพื่อเยี่ยมชมไดเรกทอรีย่อยทั้งหมดในไดเรกทอรีหลัก ทำบางสิ่งในไดเรกทอรีส่งออกไปยังไฟล์สปูลและย้ายไปยังไดเรกทอรีถัดไป พิจารณา Dir หลัก = / tmp Sub Dir = ABCD (ไดเรกทอรีย่อยสี่แห่ง)
คำตอบ:
ใช้การfor
วนซ้ำ:
for d in $(find /path/to/dir -maxdepth 1 -type d)
do
#Do something, the directory is accessible with $d:
echo $d
done >output_file
/path/to/dir
จะค้นหาเฉพาะไดเรกทอรีย่อยของไดเรกทอรี โปรดทราบว่าตัวอย่างง่ายๆข้างต้นจะล้มเหลวหากชื่อไดเรกทอรีมีช่องว่างหรืออักขระพิเศษ แนวทางที่ปลอดภัยกว่าคือ:
find /tmp -maxdepth 1 -type d -print0 |
while IFS= read -rd '' dir; do echo "$dir"; done
หรือในธรรมดาbash
:
for d in /path/to/dir/*; do
if [ -d "$d" ]; then
echo "$d"
fi
done
(โปรดทราบว่าตรงกันข้ามกับfind
ที่พิจารณา symlinks ไปยังไดเรกทอรีและแยกออกที่ซ่อนอยู่)
find
เช่นนั้น
date +"%m%d20%Y"
| xargs echo echo echo $ d
date +"%m%d20%Y"
| xargs echo echo $ d ผลลัพธ์ที่คาดหวังคือ ls -ltr จากไดเรกทอรีย่อยทั้งหมด . เหนือวงไม่ทำงาน
ฉันเป็นbash
มือใหม่ แต่เป็นทหารผ่านศึกของ UN * X แม้ว่าไม่ต้องสงสัยเลยว่าสิ่งนี้สามารถทำได้ในสคริปต์เชลล์ของ Bash แต่ในอดีตเราเคยfind [-maxdepth <levels>] <start-dir> -exec <command> ;
ประสบความสำเร็จ คุณสามารถทำman find
และเล่นไปเรื่อย ๆ จนกว่าจะมีคนบอกคุณว่าจะทำยังไงbash
!
find
คำสั่งภายนอก
$(find...)
สิ่งคือการปฏิบัติที่ไม่ดี
ดูเหมือนว่าคุณต้องการชื่อไฟล์ภายใต้แต่ละตำบล ls -l | awk
ไม่เพียงพอที่แข็งแกร่งสำหรับสิ่งที่ถ้าชื่อไฟล์เหล่านั้นประกอบด้วยช่องว่างและ / หรือการขึ้นบรรทัดใหม่? ด้านล่างfind
จะใช้งานได้แม้สำหรับfind
donot ที่เกิดขึ้นกับ-maxdepth
พวกเขา:
find . ! -name . -type d -prune -exec sh -c '
cd "$1" && \
find "." ! -name . -prune -type f
' {} {} \;
ฉันได้ทางออกแล้ว คำสั่ง find ด้านล่างตรงตามความต้องการของฉัน
find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && ls -l |awk '{ print $9 }' |grep `date +"%m%d%Y"`|xargs echo" \;
นอกจากนี้ยังสามารถใช้ ls, grep และ tr
for dir in $(ls -1FA | grep / | tr -d /); do echo $dir/something; done
ls -1FA | grep / | tr -d / | while IFS= read -r TD; do echo $TD/something; done
du / sed ยังสามารถใช้เป็นตัวเลือกได้หาก ls ของคุณไม่มีตัวเลือกด้านบน
du --max-depth=1 | sed -e 's/^.*\.\///' | grep -v '\.$'
มันอาจเป็นสิ่งสำคัญที่จะต้องทราบตัวอย่างเหล่านี้กลับไดเรกทอรีที่ซ่อนอยู่และไม่รวมไดเรกทอรีหลักและไดเรกทอรีปัจจุบัน
ls
เขียนหนึ่งไฟล์ต่อบรรทัด ( -1
ตัวเลือกที่ระบุ) โดยค่าเริ่มต้นเมื่อเอาต์พุตมาตรฐานคือไพพ์ (ดังนั้นคำตอบของคุณจึงไม่จำเป็น) (2) การแยกวิเคราะห์การส่งออกของls
เป็นความคิดที่ไม่ดี - เห็นนี้และนี้ คำตอบแรกของคุณจะล้มเหลวหากไดเรกทอรีมีช่องว่าง (หรือขึ้นบรรทัดใหม่) ในชื่อของพวกเขาและทั้งหมดจะล้มเหลวหากพวกเขามีบรรทัดใหม่ในชื่อของพวกเขา (3) คุณควรอ้างอิงตัวแปรของเชลล์ (เช่น"$dir"
) เว้นแต่คุณไม่มีเหตุผลที่ดีที่จะทำและคุณแน่ใจว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่