จากเชลล์สคริปต์ฉันจะตรวจสอบได้อย่างไรว่าไดเร็กทอรีมีไฟล์หรือไม่
สิ่งที่คล้ายกับสิ่งนี้
if [ -e /some/dir/* ]; then echo "huzzah"; fi;
แต่จะใช้งานได้ถ้าไดเร็กทอรีมีไฟล์เดียวหรือหลายไฟล์ (ไฟล์ด้านบนใช้ได้กับไฟล์ 0 หรือ 1 ไฟล์เท่านั้น)
จากเชลล์สคริปต์ฉันจะตรวจสอบได้อย่างไรว่าไดเร็กทอรีมีไฟล์หรือไม่
สิ่งที่คล้ายกับสิ่งนี้
if [ -e /some/dir/* ]; then echo "huzzah"; fi;
แต่จะใช้งานได้ถ้าไดเร็กทอรีมีไฟล์เดียวหรือหลายไฟล์ (ไฟล์ด้านบนใช้ได้กับไฟล์ 0 หรือ 1 ไฟล์เท่านั้น)
คำตอบ:
โซลูชันที่ใช้จนถึงปัจจุบัน ls
ปัจจุบัน นี่คือวิธีแก้ปัญหาทุบตีทั้งหมด:
#!/bin/bash
shopt -s nullglob dotglob # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi
shopt -q nullglob || resetnullglob=1; shopt -s nullglob; shopt -q dotglob || resetdotglob=1; shopt -s dotglob; files=(/some/dir/*); [ "$files" ] && echo "wowzers"; [ "$resetdotglob" ] && shopt -u dotglob; [ "$resetnullglob" ] && shopt -u nullglob;
files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
คำสั่ง if ควรเปลี่ยนเป็นif [ ${#files} -gt 0 ];
หรือบางทีคุณอาจลืม () รอบคำสั่ง sub-shell? files=($(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*))
shopt -s nullglob dotglob; f=your/dir/*; ((${#f}))
เคล็ดลับนี้ 100% bash
และเรียกใช้ (spawns) เปลือกย่อย แนวคิดนี้มาจากBruno De Fraineและปรับปรุงโดยความคิดเห็นของteambob
files=$(shopt -s nullglob dotglob; echo your/dir/*)
if (( ${#files} ))
then
echo "contains files"
else
echo "empty (or does not exist or is a file)"
fi
บันทึก:ไม่มีความแตกต่างระหว่างไดเร็กทอรีว่างกับไดเร็กทอรีที่ไม่มีอยู่ (และแม้ว่าพา ธ ที่ให้มาจะเป็นไฟล์ก็ตาม)
มีทางเลือกอื่นที่คล้ายกันและรายละเอียดเพิ่มเติม (และตัวอย่างเพิ่มเติม) ในคำถามที่พบบ่อย'อย่างเป็นทางการ'สำหรับช่อง #bash IRC :
if (shopt -s nullglob dotglob; f=(*); ((${#f[@]})))
then
echo "contains files"
else
echo "empty (or does not exist, or is a file)"
fi
[ -n "$(ls -A your/dir)" ]
เคล็ดลับนี้เป็นแรงบันดาลใจจากบทความ nixCraft ของโพสต์ในปี 2007 เพิ่มการปราบปรามการผิดพลาดในการส่งออก2>/dev/null
ดูคำตอบของAndrew Taylor (2008) และคำตอบของgr8can8dian (2011) ด้วย"No such file or directory"
if [ -n "$(ls -A your/dir 2>/dev/null)" ]
then
echo "contains files (or is a file)"
else
echo "empty (or does not exist)"
fi
หรือเวอร์ชัน bashism บรรทัดเดียว:
[[ $(ls -A your/dir) ]] && echo "contains files" || echo "empty"
หมายเหตุ: ls
ส่งคืน$?=2
เมื่อไม่มีไดเร็กทอรี แต่ไม่มีความแตกต่างระหว่างไฟล์และไดเร็กทอรีว่าง
[ -n "$(find your/dir -prune -empty)" ]
เคล็ดลับสุดท้ายนี้ได้รับแรงบันดาลใจจากคำตอบของ Gravstarซึ่ง-maxdepth 0
ถูกแทนที่ด้วย-prune
และปรับปรุงโดยความคิดเห็นของphils
if [ -n "$(find your/dir -prune -empty 2>/dev/null)" ]
then
echo "empty (directory or file)"
else
echo "contains files (or does not exist)"
fi
รูปแบบโดยใช้-type d
:
if [ -n "$(find your/dir -prune -empty -type d 2>/dev/null)" ]
then
echo "empty directory"
else
echo "contains files (or does not exist or is not a directory)"
fi
คำอธิบาย:
find -prune
คล้ายกว่า find -maxdepth 0
ใช้อักขระน้อยfind -empty
พิมพ์ไดเร็กทอรีว่างและไฟล์find -type d
พิมพ์ไดเร็กทอรีเท่านั้นหมายเหตุ:คุณสามารถแทนที่ได้[ -n "$(find your/dir -prune -empty)" ]
โดยใช้เวอร์ชันย่อด้านล่าง:
if [ `find your/dir -prune -empty 2>/dev/null` ]
then
echo "empty (directory or file)"
else
echo "contains files (or does not exist)"
fi
รหัสสุดท้ายนี้ใช้งานได้เกือบทุกกรณี แต่โปรดทราบว่าเส้นทางที่เป็นอันตรายอาจแสดงคำสั่ง ...
[ -n "$(find "your/dir" -prune -empty)" ]
เพื่อหลีกเลี่ยงการซ้ำซ้อนของเส้นทางไดเร็กทอรี
if [ ``ls -A your/dir`` ]
ในสคริปต์ฉันได้ข้อสรุปว่ามันทำงานได้ดีสำหรับไดเร็กทอรีที่มีไดเร็กทอรีย่อย 0, 1 หรือ 2 แต่ล้มเหลวสำหรับไดเร็กทอรีที่มีไดเร็กทอรีย่อยมากกว่า 2 ไดเร็กทอรี line 17: [: 20150424-002813: unary operator expected
ที่20150424-002813
เป็นหนึ่งในรายชื่อไดเรกทอรี เปลือกที่ใช้คือ/bin/bash/
. ในที่สุดฉันก็เปลี่ยนเป็นls "$destination" | tail -1
if [ ``ls -A my/dir`` ]
bash: [: -A: binary operator expected
ทดสอบกับ bash เวอร์ชัน 4.1.2 และ 4.2.53
-n
ตัวแปรอยู่ในพาดหัว แต่ไม่อยู่ในย่อหน้าด้านล่าง) ใช่ไม่เป็นไร
ls: cannot access '/path': No such file or directory
ยังภาพนิ่งสคริปต์ของฉันบ่นเกี่ยวกับเรื่องนี้ มีวิธีระงับข้อความนี้หรือไม่? ฉันอยากจะล้มเหลวอย่างเงียบ ๆ ที่นั่น
เกี่ยวกับสิ่งต่อไปนี้:
if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi
วิธีนี้ไม่จำเป็นต้องสร้างรายการเนื้อหาทั้งหมดของไดเร็กทอรี read
เป็นทั้งยกเลิกการออกและทำให้การแสดงออกประเมินจริงเฉพาะเมื่อสิ่งที่อ่าน (เช่น/some/dir/
พบว่าว่างเปล่าโดยfind
)
find /some/dir/ -maxdepth 0 -empty -exec echo "huzzah" \;
ls
เอาต์พุตและไม่อาศัยคุณลักษณะเชลล์ที่ไม่ใช่ค่าเริ่มต้น
-maxdepth
และ-empty
ไพรมารี
ลอง:
if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
/bin/ls <some_dir>/* 2> /dev/null
if [! -z "$ tmp"]; แล้วสะท้อนบางสิ่งบางอย่างอยู่ที่นั่น
ls /some/dir/*
]; แล้วก้อง "huzzah"; fi
-n
แทน! -z
(ทั้งคู่เทียบเท่ากัน แต่ทำไมไม่ใช้รูปแบบที่สั้นกว่าเมื่อมีอยู่)
BigGray% if [ ! -z
ls / some / dir / * `]; แล้วก้อง "huzzah"; fi zsh: ไม่พบรายการที่ตรงกัน: / some / dir / * `
ls...
ใน bash
# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
if [ "$(ls -A $1)" ]; then
echo "huzzah"
else
echo "has no files"
fi
}
ดูแลไดเรกทอรีที่มีไฟล์จำนวนมาก! อาจใช้เวลาสักครู่ในการประเมินไฟล์ls
คำสั่ง
IMO ทางออกที่ดีที่สุดคือวิธีที่ใช้
find /some/dir/ -maxdepth 0 -empty
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
echo 'There is something alive in here'
fi
คุณสามารถเปรียบเทียบผลลัพธ์ของสิ่งนี้ได้หรือไม่?
ls -A /some/dir | wc -l
# ตรวจสอบว่าไดเร็กทอรีมีไฟล์ที่ไม่ถูกซ่อนหรือไม่ # # การใช้งาน: ถ้าว่างเปล่า "$ HOME"; แล้วก้อง "ยินดีต้อนรับกลับบ้าน"; Fi # มันว่างเปล่า() { สำหรับ _ief ใน $ 1 / *; ทำ ถ้า [-e "$ _ief"]; แล้วก็ ผลตอบแทน 1 Fi เสร็จแล้ว กลับ 0 }
หมายเหตุการใช้งานบางส่วน:
for
ห่วงหลีกเลี่ยงการโทรไปยังภายนอกls
กระบวนการ มันยังคงอ่านรายการไดเรกทอรีทั้งหมดเพียงครั้งเดียว สิ่งนี้สามารถปรับให้เหมาะสมได้โดยการเขียนโปรแกรม C ที่ใช้ readdir () อย่างชัดเจนเท่านั้นtest -e
ภายในห่วงจับกรณีของไดเรกทอรีที่ว่างเปล่าซึ่งในกรณีที่ตัวแปร_ief
จะได้รับการกำหนดค่า "somedir / *" เฉพาะในกรณีที่ไฟล์นั้นมีอยู่ฟังก์ชันจะส่งคืน "nonempty"test
การดำเนินการไม่สนับสนุน-e
ธงdotglob
ไม่ได้ตั้งค่า -shopt -s dotglob
สิ่งนี้บอกฉันว่าไดเร็กทอรีว่างหรือไม่หรือไม่จำนวนไฟล์ที่มีอยู่
directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)
if [ "$number_of_files" == "0" ]; then
echo "directory $directory is empty"
else
echo "directory $directory contains $number_of_files files"
fi
ls
.
นี่อาจเป็นการตอบกลับที่ล่าช้า แต่นี่คือวิธีแก้ปัญหาที่ใช้ได้ผล บรรทัดนี้รับรู้เฉพาะการมีอยู่ของไฟล์เท่านั้น! จะไม่ให้ผลบวกปลอมหากมีไดเรกทอรีอยู่
if find /path/to/check/* -maxdepth 0 -type f | read
then echo "Files Exist"
fi
dir_is_empty() {
[ "${1##*/}" = "*" ]
}
if dir_is_empty /some/dir/* ; then
echo "huzzah"
fi
สมมติว่าคุณไม่ได้มีไฟล์ชื่อ*
เข้า/any/dir/you/check
ก็ควรจะทำงานในbash
dash
posh
busybox sh
และzsh
แต่ (สำหรับ zsh) unsetopt nomatch
จำเป็นต้องใช้
การแสดงควรเทียบได้กับการls
ใช้งาน*
(glob) ฉันเดาว่าจะช้าในไดเร็กทอรีที่มีหลายโหนด (ของฉันที่/usr/bin
มีไฟล์มากกว่า 3,000 ไฟล์ก็ไม่ช้าขนาดนั้น) จะใช้หน่วยความจำอย่างน้อยเพียงพอที่จะจัดสรร dirs / ชื่อไฟล์ทั้งหมด (และอื่น ๆ ) เนื่องจากทั้งหมดถูกส่งผ่าน (แก้ไข) ไปยังฟังก์ชันเป็นอาร์กิวเมนต์บางเชลล์อาจมีข้อ จำกัด เกี่ยวกับจำนวนอาร์กิวเมนต์และ / หรือความยาวของอาร์กิวเมนต์
วิธีการแบบพกพาที่รวดเร็ว O (1) เป็นศูนย์ทรัพยากรเพื่อตรวจสอบว่าไดเรกทอรีว่างเปล่าจะดีหรือไม่
ปรับปรุง
เวอร์ชันด้านบนไม่ได้ระบุถึงไฟล์ / dirs ที่ซ่อนอยู่ในกรณีที่จำเป็นต้องมีการทดสอบเพิ่มเติมเช่นเทคนิคis_empty
จากRich's sh (POSIX shell) :
is_empty () (
cd "$1"
set -- .[!.]* ; test -f "$1" && return 1
set -- ..?* ; test -f "$1" && return 1
set -- * ; test -f "$1" && return 1
return 0 )
แต่ฉันคิดเกี่ยวกับสิ่งนี้แทน:
dir_is_empty() {
[ "$(find "$1" -name "?*" | dd bs=$((${#1}+3)) count=1 2>/dev/null)" = "$1" ]
}
ความกังวลบางประการเกี่ยวกับการขีดทับความแตกต่างจากอาร์กิวเมนต์และผลลัพธ์ที่ค้นหาเมื่อ dir ว่างเปล่าและการขึ้นบรรทัดใหม่ต่อท้าย (แต่ควรจัดการได้ง่าย) น่าเศร้าในการbusybox
sh
แสดงของฉันสิ่งที่น่าจะเป็นข้อบกพร่องบนfind -> dd
ไปป์โดยที่เอาต์พุตถูกตัดทอนแบบสุ่ม ( ถ้าฉันใช้cat
ผลลัพธ์จะเหมือนกันเสมอดูเหมือนว่าจะdd
มีอาร์กิวเมนต์count
)
is_empty(){ [ ! -d "${1}" ] && return 2;set -- "${1}" "${1}"/* "${1}"/.[!.]* "${1}"/..?*;[ "${*}" = "${1} ${1}/* ${1}/.[!.]* ${1}/..?*" ]; };
ฉันรู้ว่าคำถามถูกทำเครื่องหมายสำหรับทุบตี แต่สำหรับการอ้างอิงสำหรับผู้ใช้zsh :
วิธีตรวจสอบว่าfoo
ว่างเปล่า:
$ for i in foo(NF) ; do ... ; done
โดยที่ถ้าfoo
ไม่ว่างรหัสในfor
บล็อกจะถูกเรียกใช้งาน
วิธีตรวจสอบว่าfoo
ว่างเปล่า:
$ for i in foo(N/^F) ; do ... ; done
โดยที่ถ้าfoo
ว่างรหัสในfor
บล็อกจะถูกเรียกใช้งาน
เราไม่จำเป็นต้องอ้างถึงไดเร็กทอรีfoo
ด้านบน แต่เราสามารถทำได้หากต้องการ:
$ for i in 'some directory!'(NF) ; do ... ; done
นอกจากนี้เรายังสามารถทดสอบมากกว่าหนึ่งวัตถุแม้ว่าจะไม่ใช่ไดเร็กทอรี:
$ mkdir X # empty directory
$ touch f # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done # echo empty directories
X
สิ่งที่ไม่ใช่ไดเร็กทอรีจะถูกละเว้น
เนื่องจากเรากำลัง globbing เราสามารถใช้ glob (หรือการขยายตัวรั้ง):
$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf # create regular file
$ touch X1/f # directory X1 is not empty
$ touch Y1/.f # directory Y1 is not empty
$ ls -F # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo # print empty directories
X X2 Y Y2
นอกจากนี้เรายังตรวจสอบวัตถุที่อยู่ในอาร์เรย์ได้อีกด้วย ด้วยไดเร็กทอรีด้านบนตัวอย่างเช่น:
$ ls -F # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*) # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z
ดังนั้นเราสามารถทดสอบวัตถุที่อาจตั้งค่าไว้แล้วในพารามิเตอร์อาร์เรย์
สังเกตว่าโค้ดในfor
บล็อกนั้นถูกเรียกใช้อย่างชัดเจนในทุกไดเร็กทอรี หากไม่เป็นที่ต้องการคุณสามารถเติมพารามิเตอร์อาร์เรย์จากนั้นดำเนินการกับพารามิเตอร์นั้น:
$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories
สำหรับผู้ใช้ zsh จะมี(F)
glob qualifier (ดูman zshexpn
) ซึ่งตรงกับไดเร็กทอรี "เต็ม" (ไม่ว่างเปล่า):
$ mkdir X Y
$ touch Y/.f # Y is now not empty
$ touch f # create a regular file
$ ls -dF * # list everything in the current directory
f X/ Y/
$ ls -dF *(F) # will list only "full" directories
Y/
Qualifier (F)
แสดงรายการอ็อบเจ็กต์ที่ตรงกัน: คือไดเร็กทอรี AND ไม่ว่างเปล่า ดังนั้นการ(^F)
จับคู่: ไม่ใช่ไดเรกทอรีหรือว่างเปล่า ดังนั้น(^F)
เพียงอย่างเดียวก็จะแสดงรายการไฟล์ปกติเช่น ดังนั้นตามที่อธิบายไว้ในzshexp
man page เราจึงต้องการ(/)
glob qualifier ซึ่งแสดงเฉพาะไดเร็กทอรี:
$ mkdir X Y Z
$ touch X/f Y/.f # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z
ดังนั้นในการตรวจสอบว่าไดเร็กทอรีที่ระบุว่างเปล่าคุณจึงสามารถรัน:
$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished
และเพื่อให้แน่ใจว่าจะไม่จับไดเร็กทอรีที่ไม่ว่างเปล่า:
$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished
อ๊ะ! เนื่องจากY
ไม่ใช่ช่องว่าง zsh จึงไม่พบรายการที่ตรงกันสำหรับ(/^F)
("ไดเร็กทอรีที่ว่าง") จึงพ่นข้อความแสดงข้อผิดพลาดที่แจ้งว่าไม่พบข้อมูลที่ตรงกันสำหรับ glob ดังนั้นเราจึงจำเป็นต้องระงับข้อความแสดงข้อผิดพลาดที่เป็นไปได้เหล่านี้ด้วย(N)
glob qualifier:
$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished
ดังนั้นสำหรับไดเร็กทอรีว่างเราจำเป็นต้องมีคุณสมบัติ(N/^F)
ซึ่งคุณสามารถอ่านได้ว่า: "อย่าเตือนฉันเกี่ยวกับความล้มเหลวไดเร็กทอรีที่ไม่เต็ม"
ในทำนองเดียวกันสำหรับไดเรกทอรีที่ไม่ว่างเปล่าเราจำเป็นต้องมีคุณสมบัติ(NF)
ซึ่งเราสามารถอ่านได้ในทำนองเดียวกันว่า: "อย่าเตือนฉันเกี่ยวกับความล้มเหลวไดเรกทอรีแบบเต็ม"
ฉันรู้สึกประหลาดใจที่ไม่มีการกล่าวถึงคู่มือการเกี้ยวในไดเรกทอรีว่าง คู่มือนี้และการเกี้ยวพาราสีทั้งหมดเป็นสิ่งที่ต้องอ่านสำหรับคำถามประเภทเชลล์
หมายเหตุจากหน้านั้น:
อย่าพยายามแยกวิเคราะห์เอาต์พุต ls แม้แต่โซลูชัน ls -A ก็สามารถพังได้ (เช่นใน HP-UX หากคุณเป็นรูท ls -A จะตรงข้ามกับสิ่งที่ทำถ้าคุณไม่ได้รูท - และไม่ฉันไม่สามารถสร้างสิ่งที่เหลือเชื่อได้ โง่).
ในความเป็นจริงเราอาจต้องการหลีกเลี่ยงคำถามโดยตรงโดยสิ้นเชิง โดยปกติผู้คนต้องการทราบว่าไดเร็กทอรีว่างหรือไม่เนื่องจากต้องการทำบางสิ่งที่เกี่ยวข้องกับไฟล์ในนั้นเป็นต้นมองไปที่คำถามที่ใหญ่กว่า ตัวอย่างเช่นหนึ่งในตัวอย่างที่ใช้ค้นหาเหล่านี้อาจเป็นวิธีแก้ปัญหาที่เหมาะสม:
# Bourne
find "$somedir" -type f -exec echo Found unexpected file {} \;
find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \; # GNU/BSD
find "$somedir" -type d -empty -exec cp /my/configfile {} \; # GNU/BSD
โดยทั่วไปสิ่งที่จำเป็นจริงๆคือสิ่งนี้:
# Bourne
for f in ./*.mpg; do
test -f "$f" || continue
mympgviewer "$f"
done
กล่าวอีกนัยหนึ่งผู้ที่ถามคำถามอาจคิดว่าจำเป็นต้องมีการทดสอบไดเร็กทอรีว่างอย่างชัดเจนเพื่อหลีกเลี่ยงข้อความแสดงข้อผิดพลาดเช่น mympgviewer: ./*.mpg: ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าวในความเป็นจริงไม่จำเป็นต้องมีการทดสอบดังกล่าว
รูปแบบเล็กน้อยของคำตอบของ Bruno :
files=$(ls -1 /some/dir| wc -l)
if [ $files -gt 0 ]
then
echo "Contains files"
else
echo "Empty"
fi
มันใช้ได้กับฉัน
คำใบ้ (หรือหลายอย่าง) จากคำตอบของ olibre ฉันชอบฟังก์ชั่น Bash:
function isEmptyDir {
[ -d $1 -a -n "$( find $1 -prune -empty 2>/dev/null )" ]
}
เพราะในขณะที่มันสร้างหนึ่ง subshell มันใกล้เคียงกับโซลูชัน O (1) เท่าที่ฉันจะจินตนาการได้และตั้งชื่อให้มันทำให้อ่านได้ จากนั้นฉันสามารถเขียน
if isEmptyDir somedir
then
echo somedir is an empty directory
else
echo somedir does not exist, is not a dir, is unreadable, or is not empty
fi
สำหรับ O (1) มีกรณีผิดปกติ: หากไดเร็กทอรีขนาดใหญ่มีทั้งหมดหรือทั้งหมดยกเว้นรายการสุดท้ายที่ถูกลบออก "find" อาจต้องอ่านข้อมูลทั้งหมดเพื่อพิจารณาว่าว่างหรือไม่ ฉันเชื่อว่าประสิทธิภาพที่คาดหวังคือ O (1) แต่กรณีที่แย่ที่สุดคือขนาดไดเร็กทอรีเชิงเส้น ฉันไม่ได้วัดสิ่งนี้
จนถึงตอนนี้ฉันยังไม่เห็นคำตอบที่ใช้ grep ซึ่งฉันคิดว่าจะให้คำตอบที่ง่ายกว่านี้ (โดยมีสัญลักษณ์แปลก ๆ ไม่มากนัก!) นี่คือวิธีที่ฉันจะตรวจสอบว่ามีไฟล์ใดอยู่ในไดเร็กทอรีโดยใช้ bourne shell:
สิ่งนี้ส่งคืนจำนวนไฟล์ในไดเร็กทอรี:
ls -l <directory> | egrep -c "^-"
คุณสามารถกรอกเส้นทางไดเร็กทอรีที่เขียนไดเร็กทอรี ครึ่งแรกของไปป์จะทำให้แน่ใจว่าอักขระตัวแรกของเอาต์พุตคือ "-" สำหรับแต่ละไฟล์ จากนั้น egrep จะนับจำนวนบรรทัดที่ขึ้นต้นด้วยสัญลักษณ์นั้นโดยใช้นิพจน์ทั่วไป ตอนนี้สิ่งที่คุณต้องทำคือเก็บหมายเลขที่คุณได้รับและเปรียบเทียบโดยใช้ backquotes เช่น:
#!/bin/sh
fileNum=`ls -l <directory> | egrep -c "^-"`
if [ $fileNum == x ]
then
#do what you want to do
fi
x เป็นตัวแปรที่คุณเลือก
ฉันได้ทำสิ่งที่ผสมลูกพรุนและคำตอบสุดท้าย
find "$some_dir" -prune -empty -type d | read && echo empty || echo "not empty"
ที่ใช้ได้กับเส้นทางที่มีช่องว่างด้วย
คำตอบง่ายๆด้วยbash :
if [[ $(ls /some/dir/) ]]; then echo "huzzah"; fi;
ฉันจะไปเพื่อfind
:
if [ -z "$(find $dir -maxdepth 1 -type f)" ]; then
echo "$dir has NO files"
else
echo "$dir has files"
การตรวจสอบผลลัพธ์ของการค้นหาเฉพาะไฟล์ในไดเร็กทอรีโดยไม่ต้องผ่านไดเร็กทอรีย่อย จากนั้นจะตรวจสอบผลลัพธ์โดยใช้-z
ตัวเลือกที่นำมาจากman test
:
-z STRING
the length of STRING is zero
ดูผลลัพธ์บางอย่าง:
$ mkdir aaa
$ dir="aaa"
ผบ.
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty
เพียงแค่เข้าไปในนั้น:
$ mkdir aaa/bbb
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty
ไฟล์ในไดเร็กทอรี:
$ touch aaa/myfile
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
$ rm aaa/myfile
ไฟล์ในไดเร็กทอรีย่อย:
$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty
ด้วยวิธีแก้ปัญหาบางอย่างฉันสามารถหาวิธีง่ายๆในการค้นหาว่ามีไฟล์อยู่ในไดเร็กทอรีหรือไม่ สิ่งนี้สามารถขยายได้มากขึ้นด้วยคำสั่ง grep เพื่อตรวจสอบไฟล์. xml หรือ. txt โดยเฉพาะเป็นต้นเช่น:ls /some/dir | grep xml | wc -l | grep -w "0"
#!/bin/bash
if ([ $(ls /some/dir | wc -l | grep -w "0") ])
then
echo 'No files'
else
echo 'Found files'
fi
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;
nullglob
เพราะls
คำสั่งจะสำเร็จ
เพื่อทดสอบไดเร็กทอรีเป้าหมายเฉพาะ
if [ -d $target_dir ]; then
ls_contents=$(ls -1 $target_dir | xargs);
if [ ! -z "$ls_contents" -a "$ls_contents" != "" ]; then
echo "is not empty";
else
echo "is empty";
fi;
else
echo "directory does not exist";
fi;
ลองใช้คำสั่งค้นหา ระบุไดเร็กทอรีฮาร์ดโค้ดหรือเป็นอาร์กิวเมนต์ จากนั้นเริ่มค้นหาเพื่อค้นหาไฟล์ทั้งหมดภายในไดเร็กทอรี ตรวจสอบว่าผลตอบแทนของการค้นหาเป็นโมฆะหรือไม่ สะท้อนข้อมูลของการค้นหา
#!/bin/bash
_DIR="/home/user/test/"
#_DIR=$1
_FIND=$(find $_DIR -type f )
if [ -n "$_FIND" ]
then
echo -e "$_DIR contains files or subdirs with files \n\n "
echo "$_FIND"
else
echo "empty (or does not exist)"
fi
ฉันไม่ชอบls - A
วิธีแก้ปัญหาที่โพสต์ เป็นไปได้มากว่าคุณต้องการทดสอบว่าไดเร็กทอรีว่างเปล่าเพราะคุณไม่ต้องการลบ ต่อไปนี้ทำเช่นนั้น อย่างไรก็ตามหากคุณต้องการบันทึกไฟล์เปล่าอย่างแน่นอนการลบและสร้างใหม่นั้นเร็วกว่าการแสดงรายการไฟล์ที่ไม่มีที่สิ้นสุดหรือไม่?
นี่น่าจะใช้ได้ ...
if ! rmdir ${target}
then
echo "not empty"
else
echo "empty"
mkdir ${target}
fi
${target}/..
นี้จะไม่ทำงานหากผู้ใช้ไม่มีสิทธิ์ในการเขียนไป
ทำงานได้ดีสำหรับฉันสิ่งนี้ (เมื่อมีผบ.):
some_dir="/some/dir with whitespace & other characters/"
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; fi
ด้วยการตรวจสอบแบบเต็ม:
if [ -d "$some_dir" ]; then
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; else "Dir is NOT empty" fi
fi