จะตรวจสอบว่าไฟล์นั้นว่างเปล่าใน Bash ได้อย่างไร?


184

ฉันมีไฟล์ชื่อ diff.txt ต้องการตรวจสอบว่าว่างเปล่าหรือไม่ ทำสิ่งนี้ แต่ไม่สามารถทำงานได้

if [ -s diff.txt ]
then
        touch empty.txt
        rm full.txt
else
        touch full.txt
        rm emtpy.txt
fi

24
[-s FILE] จริงถ้าไฟล์มีอยู่และมีขนาดใหญ่กว่าศูนย์ ดังนั้นคุณจะได้รับ "empty.txt" หาก "diff.txt" ไม่ว่างเปล่า
Matthias

2
PS: ถ้าคุณต้องการตรวจสอบการdiffโทรจริงเพียงแค่ตรวจสอบค่าตอบแทน:if diff foo.txt bar.txt; then echo 'No difference'
l0b0

20
การทดสอบสามารถถูกทำให้ยุ่งเหยิง:if [ ! -s diff.txt ]; then echo "IS EMPTY";else echo "HAS SOMETHING";fi
David Ramirez

ระวังอักขระขึ้นบรรทัดใหม่ที่ตามมา ตรวจสอบไฟล์ด้วย$ cat diff.txt | hexdump -C
Alejandro Blasco

คำตอบ:


225

การสะกดผิดน่ารำคาญใช่ไหม ตรวจสอบการสะกดของemptyคุณแล้วลองทำเช่นนี้:

#!/bin/bash -e

if [ -s diff.txt ]
then
        rm -f empty.txt
        touch full.txt
else
        rm -f full.txt
        touch empty.txt
fi

ฉันชอบเชลล์สคริปต์มาก แต่ข้อเสียอย่างหนึ่งของมันคือเชลล์ไม่สามารถช่วยคุณได้เมื่อคุณสะกดคำผิดในขณะที่คอมไพเลอร์เช่นคอมไพเลอร์ C ++ ของคุณสามารถช่วยคุณได้

สังเกตเห็นว่าฉันได้สลับบทบาทของempty.txtและfull.txtตามที่ @Matthias แนะนำ


6
เชลล์สามารถช่วยสะกดคำผิดได้ empty=empty.txt; full=full.txt; diff=diff.txt; if [ -s ${diff?} ]; then r=${empty?} t=${full?}; else r=${full?} t=${empty?}; fi; rm ${r?}; touch ${t?}
วิลเลียม Pursell

1
การใช้เครื่องมือ shellcheck สามารถค้นหาข้อผิดพลาดในการสะกดได้ดี
Yokai

1
แน่นอนว่าสิ่งนี้จะล้มเหลวหากไฟล์นั้นไม่มีอยู่? นี่ควรจะเป็นการตรวจสอบว่าไฟล์ว่างเปล่าเท่านั้น
geedoubleya

@geedoubleya: แน่นอน นั่นเป็นจุดที่สมเหตุสมผล หากการดำรงอยู่ของไฟล์นั้นมีความเกี่ยวข้อง (แน่นอนมันอาจจะเป็น) จากนั้นหนึ่งอาจปรับสคริปต์ตาม หากคุณให้สคริปต์ที่ปรับแล้วเป็นคำตอบและส่ง Ping ฉันฉันจะโหวตขึ้น
บาท

1
คุณสามารถset -u
Jon McClung


53

[[-s file]] -> ตรวจสอบว่าไฟล์มีขนาดใหญ่กว่า 0 หรือไม่

if [[ -s diff.txt ]]; then echo "file has something"; else echo "file is empty"; fi

หากจำเป็นระบบจะตรวจสอบไฟล์ * .txt ทั้งหมดในไดเรกทอรีปัจจุบัน และรายงานไฟล์เปล่าทั้งหมด:

for file in *.txt; do if [[ ! -s $file ]]; then echo $file; fi; done

3
คุณไม่จำเป็นต้องทำ$(ls *.txtและอันที่จริงไม่ควร บางคนมีค่าเริ่มต้นที่กำหนดไว้สำหรับการlsใช้รูปแบบยาว (เช่นฉัน) และเชลล์จะขยาย*.txtด้วยตนเอง เพียงแค่ทำfor file in *.txtแทน
Lilith

ดี! หากคุณต้องการตรวจสอบไฟล์ txt ทั้งหมดซ้ำคุณสามารถใช้findสิ่งนี้:for file in $(find . -name '*.txt'); do if [[ ! -s $file ]]; then echo $file; fi; done
KlimczakM

1
Downvoted for file in $(ls *.txt); doเพียงเพราะเรื่องนี้ต่อต้านรูปแบบที่น่ากลัว โปรดใช้for file in *.txt; doแทน โปรดอ่านหน้า Bash Pitfalls ; และโปรดหยุดการแพร่กระจาย antipatterns เช่นนี้
gniourf_gniourf

8

ในขณะที่คำตอบอื่น ๆ นั้นถูกต้องการใช้"-s"ตัวเลือกนี้จะแสดงว่าไฟล์นั้นว่างเปล่าแม้ว่าไฟล์นั้นจะไม่มีอยู่ก็ตาม
โดยการเพิ่มการตรวจสอบเพิ่มเติมนี้"-f"เพื่อดูว่ามีไฟล์อยู่ก่อนหรือไม่เรามั่นใจว่าผลลัพธ์นั้นถูกต้อง

if [ -f diff.txt ]
then
  if [ -s diff.txt ]
  then
    rm -f empty.txt
    touch full.txt
  else
    rm -f full.txt
    touch empty.txt
  fi
else
  echo "File diff.txt does not exist"
fi

4

@geedoubleyaคำตอบคือที่ชื่นชอบ

อย่างไรก็ตามฉันชอบสิ่งนี้

if [[ -f diff.txt && -s diff.txt ]]
then
  rm -f empty.txt
  touch full.txt
elif [[ -f diff.txt && ! -s diff.txt ]]
then
  rm -f full.txt
  touch empty.txt
else
  echo "File diff.txt does not exist"
fi

3

ในการตรวจสอบว่าไฟล์ว่างเปล่าหรือมีช่องว่างสีขาวเท่านั้นคุณสามารถใช้ grep:

if [[ -z $(grep '[^[:space:]]' $filename) ]] ; then
  echo "Empty file" 
  ...
fi

นี่เป็นคำตอบเดียวที่ดีและควรเป็นคำตอบที่ยอมรับได้ การใช้-sไม่ตอบคำถาม ค้นหาไฟล์ที่มีอยู่และมีขนาดมากกว่า 0 ไบต์
Akito

2

หลายคำตอบนั้นถูกต้อง แต่ฉันรู้สึกว่ามันอาจจะสมบูรณ์ / ง่ายขึ้นเป็นต้นเช่น:

ตัวอย่างที่ 1: พื้นฐานถ้าคำสั่ง

# BASH4+ example on Linux :

typeset read_file="/tmp/some-file.txt"
if [ ! -s "${read_file}" ]  || [ ! -f "${read_file}" ] ;then
    echo "Error: file (${read_file}) not found.. "
    exit 7
fi

ถ้า $ read_file ว่างเปล่าหรือไม่มีให้หยุดการแสดงด้วยการออก มากกว่าหนึ่งครั้งฉันได้อ่านคำตอบที่ผิดที่นี่เพื่อหมายถึงสิ่งที่ตรงกันข้าม

ตัวอย่างที่ 2: เป็นฟังก์ชั่น

# -- Check if file is missing /or empty --
# Globals: None
# Arguments: file name
# Returns: Bool
# --
is_file_empty_or_missing() {
    [[ ! -f "${1}" || ! -s "${1}" ]] && return 0 || return 1
}


0

ฉันมาที่นี่เพื่อค้นหาวิธีการลบ__init__.pyไฟล์ว่างเปล่าเนื่องจากไฟล์เหล่านั้นมีนัยใน Python 3.3+ และสิ้นสุดลงโดยใช้:

find -depth '(' -type f  -name __init__.py ')' -print0 |
  while IFS= read -d '' -r file; do if [[ ! -s $file ]]; then rm $file; fi; done

นอกจากนี้ (อย่างน้อยก็เป็น zsh) โดยใช้ $ path เนื่องจากตัวแปรจะแบ่ง $ PATH env ของคุณและมันจะทำให้เชลล์ที่เปิดของคุณแตก อย่างไรก็ตามคิดว่าฉันจะแบ่งปัน!


0

วิธีที่ง่ายที่สุดสำหรับการตรวจสอบไฟล์ว่างเปล่าหรือไม่:

if [ -s /path-to-file/filename.txt ]
then
     echo "File is not empty"
else
     echo "File is empty"
fi

คุณสามารถเขียนมันในบรรทัดเดียว:

[ -s /path-to-file/filename.txt ] && echo "File is not empty" || echo "File is empty"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.