बैश का उपयोग करके किसी फ़ाइल का आकार कैसे जांचें?


145

मुझे एक स्क्रिप्ट मिली है जो 0-आकार की जांच करती है, लेकिन मैंने सोचा कि इसके बजाय फ़ाइल आकार की जांच करने का एक आसान तरीका होना चाहिए। Ie file.txtसामान्य रूप से 100k है; अगर यह 90k (0 सहित) से कम है, तो स्क्रिप्ट की जांच कैसे करें और इसे एक नई प्रतिलिपि के लिए तैयार करें क्योंकि इस मामले में फ़ाइल भ्रष्ट है।

मैं वर्तमान में क्या उपयोग कर रहा हूँ ..

if [ -n file.txt ]
then
 echo "everything is good"
else
 mail -s "file.txt size is zero, please fix. " myemail@gmail.com < /dev/null
 # Grab wget as a fallback 
 wget -c https://www.server.org/file.txt -P /root/tmp --output-document=/root/tmp/file.txt
 mv -f /root/tmp/file.txt /var/www/file.txt
fi

जवाबों:


250

[ -n file.txt ]इसके आकार की जांच नहीं करता है, यह जांचता है कि स्ट्रिंग file.txtगैर-शून्य लंबाई है, इसलिए यह हमेशा सफल होगा।

यदि आप "आकार गैर-शून्य" कहना चाहते हैं, तो आपको आवश्यकता है [ -s file.txt ]

फ़ाइल का आकार प्राप्त करने के लिए, आप wc -cबाइट में आकार (फ़ाइल की लंबाई) प्राप्त करने के लिए उपयोग कर सकते हैं :

file=file.txt
minimumsize=90000
actualsize=$(wc -c <"$file")
if [ $actualsize -ge $minimumsize ]; then
    echo size is over $minimumsize bytes
else
    echo size is under $minimumsize bytes
fi

इस मामले में, ऐसा लगता है कि आप क्या चाहते हैं।

लेकिन FYI करें, यदि आप जानना चाहते हैं कि फ़ाइल का उपयोग du -kकरने के लिए डिस्क स्थान कितना है, तो आप किलोबाइट्स में आकार (डिस्क स्थान का उपयोग) प्राप्त करने के लिए उपयोग कर सकते हैं :

file=file.txt
minimumsize=90
actualsize=$(du -k "$file" | cut -f 1)
if [ $actualsize -ge $minimumsize ]; then
    echo size is over $minimumsize kilobytes
else
    echo size is under $minimumsize kilobytes
fi

यदि आपको आउटपुट प्रारूप पर अधिक नियंत्रण की आवश्यकता है, तो आप इसे भी देख सकते हैं stat। लिनक्स पर, आप कुछ की तरह stat -c '%s' file.txt, और बीएसडी / मैक ओएस एक्स पर, कुछ इस तरह से शुरुआत करेंगे stat -f '%z' file.txt


5
du -b "$file" | cut -f 1इसके बजाय क्यों stat -c '%s' "$file"? या stat --printf="%s" "$file"?
mivk

1
केवल इसलिए कि यह अधिक पोर्टेबल है। बीएसडी और लिनक्स के stat अलग-अलग झंडे हैं।
मिकेल

1
... | cut -d' ' -f1उबंटू पर काम करने के लिए मुझे इसे संशोधित करना पड़ा ।
माइकपोते

8
उपयोग करें wc -c < "$file"(नोट करें <), जिस स्थिति में आपको | cut ...भाग की आवश्यकता नहीं है (जो, जैसा कि पोस्ट किया गया है, OSX पर काम नहीं करता है)। OSX पर न्यूनतम BLOCKSIZEमूल्य duहै 512
mklement0

3
@PetriSirkkala मेरे लिनक्स सिस्टम पर wc -c <filenameभी उपयोग करता है fstatऔर seek? ध्यान दें कि fstatएक fd लेता है, एक pathname नहीं।
मिकेल

24

यह आश्चर्य की बात है कि किसी ने statफ़ाइल आकार की जांच करने का उल्लेख नहीं किया । कुछ तरीके निश्चित रूप से बेहतर हैं: -sयह पता लगाने के लिए कि क्या फ़ाइल खाली है या नहीं, किसी अन्य चीज़ की तुलना में आसान है यदि आप चाहते हैं। और यदि आप किसी आकार की फाइल ढूंढना चाहते हैं , तो findनिश्चित रूप से जाने का रास्ता है।

मुझे भी dukb में फ़ाइल साइज़ प्राप्त करना बहुत पसंद है, लेकिन, बाइट्स के लिए, मैं उपयोग करूँगा stat:

size=$(stat -f%z $filename) # BSD stat

size=$(stat -c%s $filename) # GNU stat?

2
statएक महान विचार है, लेकिन CentOS पर मेरे लिए यही काम किया गया है:size=$(stat -c%s $filename)
Oz Solomon

2
जीएनयू और बीएसडी के बीच का अंतर, दुर्भाग्य से, इस विकल्प को थोड़ा कम आकर्षक बनाता है। :(
लैपो

1
यदि फ़ाइल विरल है तो स्टेट भ्रामक हो सकता है। आप उपयोग किए गए स्थान की गणना करने के लिए स्टेट द्वारा रिपोर्ट किए गए ब्लॉकों का उपयोग कर सकते हैं।
अजित एंटनी

@AjithAntony यह एक दिलचस्प बिंदु है जो मेरे साथ नहीं हुआ। मैं देख सकता हूँ statजा रहा है सही कुछ स्थितियों में बात है, और स्पार्स फ़ाइलों ज्यादातर स्थितियों में प्रासंगिक नहीं हैं, हालांकि निश्चित रूप से बिल्कुल नहीं।
डैनियल सी। सोबराल

17

awk और डबल कोष्ठक के साथ वैकल्पिक समाधान:

FILENAME=file.txt
SIZE=$(du -sb $FILENAME | awk '{ print $1 }')

if ((SIZE<90000)) ; then 
    echo "less"; 
else 
    echo "not less"; 
fi

1
अच्छा है, लेकिन OSX पर काम नहीं करेगा, जहां duसमर्थन नहीं करता है -b। (: आप छोड़ सकते हैं यह एक सचेत शैली विकल्प हो सकता है, लेकिन सिर्फ विकल्प का उल्लेख $उपसर्ग के अंदर (( ... )): जब चर संदर्भित ((SIZE<90000)))
mklement0

1
वास्तव में यह एक पिछले उपयोगकर्ता का एक संपादन था जिसने सोचा था कि $
fstab

2
@fstab, आप ( आंतरिक कमांड) awkका उपयोग करके ommit कर सकते हैं :readbashread SIZE _ <<<$(du -sb "$FILENAME")
Jadian

13

यदि आपका findसिंटैक्स इस संभालता है, तो आप इसका उपयोग कर सकते हैं:

find -maxdepth 1 -name "file.txt" -size -90k

यह file.txtऔर अगर केवल file.txt90k से कम है , तो stdout को आउटपुट देगा । एक स्क्रिप्ट को निष्पादित करने के लिए scriptकरता है, तो file.txtएक आकार 90k से कम है:

find -maxdepth 1 -name "file.txt" -size -90k -exec script \;

3
+1, लेकिन यह OSX पर काम करने के लिए, आपको एक स्पष्ट लक्ष्य निर्देशिका तर्क चाहिए, जैसे:find . -maxdepth 1 -name "file.txt" -size -90k
mklement0

8

यदि आप किसी फ़ाइल के आकार की तलाश कर रहे हैं:

$ cat $file | wc -c
> 203233

1
यह सबसे कम व्यावहारिक जवाब हो सकता है, लेकिन यह शायद सबसे धीमा भी है। :)
सनस्पार्क

2
हां, लेकिन निश्चित रूप से आर्थिक रूप से बेहतर: इंजीनियरिंग समय की लागत> संगणना समय की लागत
बनानाल

8
wc -c "$file"2011 (तीन साल पहले) में एक उत्तर के रूप में दिया गया था। हां, wc -c "$file"यह समस्या है कि यह फ़ाइल नाम के साथ-साथ वर्ण गणना को भी आउटपुट करता है, इसलिए प्रारंभिक उत्तरों ने गिनती को अलग करने के लिए एक कमांड जोड़ा। लेकिन wc -c < "$file", जो उस समस्या को ठीक करता है, उसे मई 2014 में एक टिप्पणी के रूप में जोड़ा गया था। आपका जवाब इसके बराबर है, सिवाय इसके कि यह "बेकार उपयोग cat" है । इसके अलावा, आपको सभी शेल चर संदर्भों को उद्धृत करना चाहिए जब तक कि आपके पास एक अच्छा कारण न हो।
जी-मैन का कहना है कि 'मोनिका' को

1
आप cat.if [$ (हेड -c 90000 $ फ़ाइल | wc -c) -900 90000] के बजाय हेड -c का उपयोग करके इसे और अधिक कुशल बना सकते हैं; तब गूंज "फ़ाइल 90k से छोटी है"; फाई। CentOS पर परीक्षण किया गया है, इसलिए यह BSD या OSX पर काम कर भी सकता है और नहीं भी।
केविन कीन

@BananaNeil इस प्रक्रिया को प्रत्येक 20 सेकंड में कैसे करें ताकि मैं फ़ाइल आकार में वृद्धि की जाँच कर सकूँ?
एक सहरा

6

यह linux और macos दोनों में काम करता है

function filesize
{
    local file=$1
    size=`stat -c%s $file 2>/dev/null` # linux
    if [ $? -eq 0 ]
    then
        echo $size
        return 0
    fi

    eval $(stat -s $file) # macos
    if [ $? -eq 0 ]
    then
        echo $st_size
        return 0
    fi

    return -1
}

5

स्टेट सबसे कम सिस्टम कॉल के साथ ऐसा करने के लिए प्रतीत होता है:

$ set debian-live-8.2.0-amd64-xfce-desktop.iso

$ strace stat --format %s $1 | wc
    282    2795   27364

$ strace wc --bytes $1 | wc
    307    3063   29091

$ strace du --bytes $1 | wc
    437    4376   41955

$ strace find $1 -printf %s | wc
    604    6061   64793

अगर मैं यह सही ढंग से समझ, परीक्षण भी पाइप पुनर्निर्देशन ?: से किया जाना चाहिए strace du --bytes $1 2>&1 >/dev/null | wc अगर ऐसा है, तो ArchLinux (सब कुछ का आमतौर पर नवीनतम संस्करण) मैं के लिए 45 लाइनों पर amd64 वास्तुकला पर du, के लिए 46 लाइनों stat, के लिए 47 लाइनों wcऔर 72 लाइनों के लिए find
वासिलीनोविकोव

5
python -c 'import os; print (os.path.getsize("... filename ..."))'

पोर्टेबल, अजगर के सभी स्वाद, स्टेट्स बोलियों में भिन्नता से बचते हैं


4

लिनक्स और मैक ओएस एक्स (और संभवतः अन्य बीएसडी) दोनों में फ़ाइल आकार प्राप्त करने के लिए, कई विकल्प नहीं हैं, और यहां सुझाए गए अधिकांश केवल एक सिस्टम पर काम करेंगे।

दिया f=/path/to/your/file,

लिनक्स और मैक बैश दोनों में क्या काम करता है :

size=$( perl -e 'print -s shift' "$f" )

या

size=$( wc -c "$f" | awk '{print $1}' )

अन्य उत्तर लिनक्स में ठीक काम करते हैं, लेकिन मैक में नहीं:

  • du-bमैक में एक विकल्प नहीं है , और BLOCKSIZE = 1 ट्रिक काम नहीं करता है ("न्यूनतम अवरोधन 512 है", जो गलत परिणाम की ओर ले जाता है)

  • cut -d' ' -f1 मैक पर काम नहीं करता है, संख्या सही-संरेखित हो सकती है, सामने रिक्त स्थान के साथ गद्देदार।

तो अगर आप कुछ लचीला की जरूरत है, यह या तो है perlकी -sऑपरेटर, या wc -cकरने के लिए पहुंचाया awk '{print $1}'(awk प्रमुख सफेद स्थान पर ध्यान नहीं देगा)।

और हां, अपने बाकी मूल प्रश्न के संबंध में, -lt(या -gt) ऑपरेटर का उपयोग करें :

if [ $size -lt $your_wanted_size ]; then आदि।


3
+1; यदि आप जानते हैं कि आप केवल एक अंकगणित के संदर्भ में आकार का उपयोग कर रहे हैं (जहां अग्रणी व्हाट्सएप को नजरअंदाज किया जाता है), तो आप इसे सरल कर सकते हैं size=$(wc -c < "$f")(ध्यान दें <, जो wcकेवल एक संख्या की रिपोर्ट करने का कारण बनता है)। तुलना करें: अधिक "बैश-फ़ुल" if (( size < your_wanted_size )); then ...(और भी [[ $size -lt $your_wanted_size ]]) मत भूलना ।
mklement0

3

Gniourf_gniourf के उत्तर के आधार पर,

find "file.txt" -size -90k

लिखेंगे file.txtstdout करने के लिए करता है, तो और का आकार केवल तभी file.txt, 90K से कम है और

"file.txt" खोजें -size -90k -exec कमांड \;

आदेश पर अमल होगा commandअगर file.txtएक आकार 90K से कम है। मैंने लिनक्स पर इसका परीक्षण किया है। से find(1),

… ( -H, -Lऔर -Pविकल्प) के बाद कमांड-लाइन तर्क की जांच की जाने वाली फ़ाइलों या निर्देशिकाओं का नाम लिया जाता है , जो पहले तर्क तक '-', ... से शुरू होती है।

(महत्व दिया)।


1
ls -l $file | awk '{print $6}'

यह मानते हुए कि ls कमांड रिपोर्ट कॉलम # 6 पर फाइल करती है


1

मैं का प्रयोग करेंगे dus ' --thresholdइस बात के लिए। निश्चित नहीं है कि यह विकल्प सभी संस्करणों में उपलब्ध है, duलेकिन यह GNU के संस्करण में लागू किया गया है।

डु (1) मैनुअल से उद्धृत :

-t, --threshold=SIZE
       exclude entries smaller than SIZE if positive, or entries greater
       than SIZE if negative

यहाँ मेरा समाधान है, du --threshold=ओपी के उपयोग के मामले के लिए उपयोग:

THRESHOLD=90k
if [[ -z "$(du --threshold=${THRESHOLD} file.txt)" ]]; then
    mail -s "file.txt size is below ${THRESHOLD}, please fix. " myemail@gmail.com < /dev/null
    mv -f /root/tmp/file.txt /var/www/file.txt
fi

इसका लाभ यह है कि, duएक ज्ञात प्रारूप में उस विकल्प के लिए एक तर्क को स्वीकार कर सकता है - या तो मानव के रूप में 10K, 10MiBया क्या आप कभी भी सहज महसूस करते हैं - आपको duहैंडल के बाद से मैन्युअल / इकाइयों के बीच मैन्युअल रूप से परिवर्तित करने की आवश्यकता नहीं है।

संदर्भ के लिए, SIZEमैन पेज से इस तर्क पर स्पष्टीकरण यहां दिया गया है :

The SIZE argument is an integer and optional unit (example: 10K is 
10*1024). Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers
of 1000). Binary prefixes can be used, too: KiB=K, MiB=M, and so on.

+1 उत्कृष्ट विकल्प। दुर्भाग्य से हम में से कुछ पुराने संस्करणों के साथ फंसे हुए हैं duजो इसका समर्थन नहीं करते हैं। --thresholdविकल्प coreutils 8.21 में जोड़ा गया है, 2013 में जारी किया गया
अमित नायडू

1

ठीक है, अगर आप एक मैक पर हैं, तो यह करें: stat -f %z "/Users/Example/config.log" यह बात है!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.