ฉันจะรับขนาดไฟล์ในสคริปต์ทุบตีได้อย่างไร
ฉันจะกำหนดสิ่งนี้ให้กับตัวแปร bash ได้อย่างไรเพื่อใช้ในภายหลัง
pvและcatสำหรับคำสั่งคัดลอกที่แสดงความคืบหน้าและ ETA :)
ฉันจะรับขนาดไฟล์ในสคริปต์ทุบตีได้อย่างไร
ฉันจะกำหนดสิ่งนี้ให้กับตัวแปร bash ได้อย่างไรเพื่อใช้ในภายหลัง
pvและcatสำหรับคำสั่งคัดลอกที่แสดงความคืบหน้าและ ETA :)
คำตอบ:
ทางออกที่ดีที่สุดของคุณหากอยู่ในระบบ GNU:
stat --printf="%s" file.any
จากผู้ชายสถิติ :
ขนาดรวม% s หน่วยเป็นไบต์
ในสคริปต์ทุบตี:
#!/bin/bash
FILENAME=/home/heiko/dummy/packages.txt
FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."
หมายเหตุ: ดูคำตอบของ @ chbrownสำหรับวิธีใช้ stat ในเทอร์มินัลบน Mac OS X
statเป็นวิธีที่ตรงไปตรงมาที่สุดโดยสมมติว่าคุณใช้ Linux หรือ Cygwin ( statไม่ใช่มาตรฐาน) wc -cตามที่แนะนำโดยEugéneเป็นแบบพกพา
stat: illegal option -- c
stat --printf="%s" file.txtได้ทำอะไรเลยไม่เอาท์พุทใน Debian เจสซี ...
stat -f%z myfile.tar
man statกล่าวว่า --printf ละเว้นการขึ้นบรรทัดใหม่ ใช้--formatหรือ-cเพื่อดูผลลัพธ์ รับข้อมูลเชิงลึกมากขึ้นโดยเปรียบเทียบstat --printf="%s" file.any | xxd -กับstat -c "%s" file.any | xxd -
file_size_kb=`du -k "$filename" | cut -f1`
ปัญหาเกี่ยวกับการใช้statคือมันเป็นส่วนขยาย GNU (Linux) du -kและcut -f1มีการระบุโดย POSIX และดังนั้นจึงพกพาไปยังระบบ Unix ใด ๆ
Solaris, ตัวอย่างเช่นมาพร้อมกับทุบตี statแต่ไม่ได้มี นี่ไม่ใช่สมมุติทั้งหมด
lsมีปัญหาที่คล้ายกันซึ่งไม่ได้ระบุรูปแบบที่แน่นอนของเอาต์พุตดังนั้นการวิเคราะห์เอาต์พุตจึงไม่สามารถทำได้แบบพกพา du -hยังเป็นส่วนขยายของ GNU
ยึดติดกับโครงสร้างแบบพกพาหากเป็นไปได้และคุณจะทำให้ชีวิตของใครบางคนง่ายขึ้นในอนาคต อาจเป็นของคุณเอง
duไม่ได้ให้ขนาดของไฟล์มันแสดงให้เห็นว่ามีการใช้พื้นที่ไฟล์มากน้อยเพียงใดซึ่งแตกต่างอย่างละเอียด (โดยปกติแล้วขนาดที่รายงานduคือขนาดของไฟล์จะถูกปัดเศษขึ้นเป็นจำนวนบล็อกที่ใกล้ที่สุดโดยที่บล็อก โดยทั่วไปแล้วจะเป็น 512B หรือ 1kB หรือ 4kB)
--bytesหรือ-bแทน-kควรจะเป็นคำตอบที่ได้รับการยอมรับ
-h( "มนุษย์") ตัวเลือกในการduจะผลิตคำตอบที่เหมาะสมที่สุดสำหรับกรณีทั่วไป: file_size=`du -h "$filename" | cut -f1เป็นมันจะแสดง K (กิโลไบต์), M (เมกะไบต์) หรือ G (กิกะไบต์) ตามความเหมาะสม
คุณสามารถใช้คำสั่ง "นับจำนวนคำ" ( wc):
wc -c "$filename" | awk '{print $1}'
ปัญหาwcคือมันจะเพิ่มชื่อไฟล์และเยื้องออก ตัวอย่างเช่น:
$ wc -c somefile.txt
1160 somefile.txt
หากคุณต้องการหลีกเลี่ยงการโยงภาษาที่ถูกตีความหรือตัวแก้ไขสตรีมเพื่อให้ได้ขนาดไฟล์ให้เปลี่ยนเส้นทางอินพุตจากไฟล์เพื่อwcไม่ให้เห็นชื่อไฟล์:
wc -c < "$filename"
แบบฟอร์มสุดท้ายนี้สามารถใช้กับการทดแทนคำสั่งเพื่อจับค่าที่คุณต้องการเป็นตัวแปรเชลล์ได้อย่างง่ายดายตามที่Gillesระบุไว้ด้านล่าง
size="$(wc -c <"$filename")"
wc -c <"$FILENAME"ให้มีขนาดที่ไม่มี cruft อื่น ๆ size=$(wc -c <"$FILENAME")จึง
wc -c < fileดูเหมือนว่าจะเร็วมากอย่างน้อยใน OS X ฉันเดาว่า wc มีสมองที่จะลองจัดเก็บไฟล์หากระบุ -c ไว้เท่านั้น
wc -cใช้fstatแต่จากนั้นค้นหาบล็อกสุดท้ายของไฟล์และอ่านst_blksizeไบต์สูงสุดล่าสุด เห็นได้ชัดว่าเป็นเพราะไฟล์ใน Linux /procและ/sysตัวอย่างมีขนาดสถิติที่เป็นค่าโดยประมาณเท่านั้นและwcต้องการรายงานขนาดจริงไม่ใช่ขนาดสถิติที่รายงาน ฉันคิดว่ามันคงจะแปลกสำหรับwc -cการรายงานขนาดที่แตกต่างกว่าwcแต่ไม่ควรอ่านข้อมูลจากไฟล์ถ้ามันเป็นไฟล์ดิสก์ปกติและไม่ใช่ในหน่วยความจำ หรือการจัดเก็บเทปที่เลวร้ายยิ่งใกล้เส้น ...
printfยังคงเห็นการเยื้องเช่น->printf "Size: $size" size: <4 spaces> 54339ในทางกลับกันechoช่องว่างไม่สนใจ มีวิธีใดที่จะทำให้มันสอดคล้องกัน?
fstatโดยการเรียก ลองใช้strace wc -c </etc/passwdและคุณจะเห็นสิ่งที่กำลังทำ
BSD's (Mac OS X's) statมีการตั้งค่าสถานะอาร์กิวเมนต์รูปแบบที่แตกต่างกันและตัวระบุฟิลด์ที่แตกต่างกัน จากman stat(1):
-f format: แสดงข้อมูลโดยใช้รูปแบบที่ระบุ ดูส่วน FORMATS สำหรับคำอธิบายของรูปแบบที่ถูกต้องz: ขนาดของไฟล์เป็นไบต์ดังนั้นทั้งหมดเข้าด้วยกันตอนนี้:
stat -f%z myfile1.txt
ขึ้นอยู่กับสิ่งที่คุณหมายถึงขนาด
size=$(wc -c < "$file")
จะให้จำนวนไบต์ที่สามารถอ่านได้จากไฟล์ IOW มันคือขนาดของเนื้อหาของไฟล์ อย่างไรก็ตามมันจะอ่านเนื้อหาของไฟล์ (ยกเว้นว่าไฟล์เป็นไฟล์ปกติหรือ symlink ไปยังไฟล์ปกติในwcการปรับใช้ส่วนใหญ่เป็นการปรับให้เหมาะสม) ที่อาจมีผลข้างเคียง ตัวอย่างเช่นสำหรับไปป์ที่มีชื่อสิ่งที่ถูกอ่านไม่สามารถอ่านได้อีกต่อไปและสำหรับสิ่งที่ชอบ/dev/zeroหรือ/dev/randomขนาดที่ไม่มีที่สิ้นสุดมันจะต้องใช้เวลาสักครู่ นั่นหมายความว่าคุณต้องreadได้รับอนุญาตจากไฟล์และเวลาการเข้าถึงล่าสุดของไฟล์อาจได้รับการอัพเดต
นั่นเป็นมาตรฐานและพกพาอย่างไรก็ตามโปรดทราบว่าwcการใช้งานบางอย่างอาจรวมถึงช่องว่างชั้นนำในผลลัพธ์นั้น วิธีหนึ่งในการกำจัดพวกเขาคือการใช้:
size=$(($(wc -c < "$file")))
หรือเพื่อหลีกเลี่ยงข้อผิดพลาดเกี่ยวกับนิพจน์ทางคณิตศาสตร์ที่ว่างเปล่าในdashหรือyashเมื่อwcไม่สร้างเอาต์พุต (เช่นเมื่อไฟล์ไม่สามารถเปิดได้):
size=$(($(wc -c < "$file") +0))
ksh93มีwcbuiltin (หากคุณเปิดใช้งานคุณยังสามารถเรียกใช้เป็นcommand /opt/ast/bin/wc) ซึ่งทำให้ประสิทธิภาพสูงสุดสำหรับไฟล์ปกติในเชลล์นั้น
ระบบต่าง ๆ มีคำสั่งที่เรียกstatว่าเป็นส่วนต่อประสานกับการโทรstat()หรือlstat()ระบบ
ข้อมูลรายงานเหล่านั้นพบในไอโหนด หนึ่งในข้อมูลนั้นคือst_sizeแอตทริบิวต์ สำหรับไฟล์ปกตินั่นคือขนาดของเนื้อหา (จำนวนข้อมูลที่สามารถอ่านได้ในกรณีที่ไม่มีข้อผิดพลาด (นั่นคือสิ่งที่แอพพลิเคชั่นส่วนใหญ่wc -cใช้ในการปรับให้เหมาะสม) สำหรับ symlink นั่นคือขนาดเป็นไบต์ของพา ธ เป้าหมาย สำหรับไพพ์ที่มีชื่อขึ้นอยู่กับระบบมันเป็น 0 หรือจำนวนไบต์ในบัฟเฟอร์ไพพ์ เช่นเดียวกับอุปกรณ์บล็อกที่ขึ้นอยู่กับระบบคุณจะได้รับ 0 หรือขนาดเป็นไบต์ของที่เก็บข้อมูลพื้นฐาน
คุณไม่จำเป็นต้องได้รับอนุญาตให้อ่านไฟล์เพื่อรับข้อมูลนั้นเพียงค้นหาสิทธิ์ในไดเรกทอรีที่ลิงก์ไปเท่านั้น
ตามลำดับมี:
IRIXstat (90's):
stat -qLs -- "$file"
ส่งคืนst_sizeแอตทริบิวต์ของ$file( lstat()) หรือ:
stat -s -- "$file"
เดียวกันยกเว้นเมื่อ$fileเป็น symlink ซึ่งในกรณีนี้มันเป็นst_sizeไฟล์หลังจากการแก้ปัญหา symlink
zsh statbuiltin (ตอนนี้เรียกอีกอย่างว่าzstat) ในzsh/statโมดูล (โหลดด้วยzmodload zsh/stat) (1997):
stat -L +size -- $file # st_size of file
stat +size -- $file # after symlink resolution
หรือเก็บไว้ในตัวแปร:
stat -L -A size +size -- $file
เห็นได้ชัดว่ามันมีประสิทธิภาพมากที่สุดในเชลล์นั้น
GNUstat (2001); ยังอยู่ใน BusyBox statตั้งแต่ปี 2005 (คัดลอกมาจาก GNU stat):
stat -c %s -- "$file" # st_size of file
stat -Lc %s -- "$file" # after symlink resolution
(ทราบความหมายของ-Lถูกกลับรายการเมื่อเทียบกับ IRIX zsh statหรือ
BSDsstat (2002):
stat -f %z -- "$file" # st_size of file
stat -Lf %z -- "$file" # after symlink resolution
หรือคุณสามารถใช้stat()/ lstat()ฟังก์ชันของภาษาสคริปต์บางอย่างเช่นperl:
perl -le 'print((lstat shift)[7])' -- "$file"
AIX ยังมีistatคำสั่งที่จะดัมพ์ข้อมูลstat()(ไม่ใช่lstat()ดังนั้นจะไม่ทำงานบน symlink) และคุณสามารถโพสต์กระบวนการด้วยตัวอย่างเช่น:
LC_ALL=C istat "$file" | awk 'NR == 4 {print $5}'
(ขอบคุณ @JeffSchaller สำหรับความช่วยเหลือในการหารายละเอียด )
ในtcsh:
@ size = -Z $file:q
(ขนาดหลังจากความละเอียด symlink)
นานก่อนที่ GNU จะเปิดตัวstatคำสั่งมันสามารถทำได้โดยใช้findคำสั่งGNU พร้อม-printfคำอธิบาย (ในปี 1991 แล้ว):
find -- "$file" -prune -printf '%s\n' # st_size of file
find -L -- "$file" -prune -printf '%s\n' # after symlink resolution
แม้ว่าปัญหาหนึ่งคือว่าจะไม่ทำงานหาก$fileเริ่มต้นด้วย-หรือเป็นเพรดิเคตfind(เช่น!, (... )
คำสั่งมาตรฐานที่จะได้รับstat()/ ข้อมูลlstat()ls
POSIXly คุณสามารถทำ:
LC_ALL=C ls -dn -- "$file" | awk '{print $5; exit}'
และเพิ่ม-Lให้เหมือนกันหลังจากความละเอียด symlink แต่นั่นไม่ได้ทำงานให้กับแฟ้มอุปกรณ์แม้ว่าที่ 5 ณสนามเป็นจำนวนที่สำคัญอุปกรณ์แทนของขนาด
สำหรับอุปกรณ์บล็อกระบบที่stat()ส่งคืนค่า 0 st_sizeมักจะมี API อื่นเพื่อรายงานขนาดของอุปกรณ์บล็อก ตัวอย่างเช่น Linux มีBLKGETSIZE64 ioctl()และดิสทริบิวชันส่วนใหญ่มาพร้อมกับblockdevคำสั่งที่สามารถใช้ประโยชน์ได้แล้ว:
blockdev --getsize64 -- "$device_file"
อย่างไรก็ตามคุณต้องได้รับอนุญาตในการอ่านไฟล์อุปกรณ์สำหรับสิ่งนั้น เป็นไปได้ที่จะหาขนาดด้วยวิธีอื่น ตัวอย่างเช่น (ยังอยู่บน Linux):
lsblk -bdno size -- "$device_file"
ควรทำงานยกเว้นอุปกรณ์ที่ว่างเปล่า
วิธีการที่เหมาะกับทุกseekableไฟล์ (เพื่อให้รวมถึงไฟล์ปกติอุปกรณ์ป้องกันและอุปกรณ์ส่วนใหญ่ตัวละครบางคน) คือการเปิดไฟล์และหาทางที่จะสิ้นสุด:
ด้วยzsh(หลังจากโหลดzsh/systemโมดูล):
{sysseek -w end 0 && size=$((systell(0)))} < $fileด้วยksh93:
< "$file" <#((size=EOF))
หรือ
{ size=$(<#((EOF))); } < "$file"ด้วยperl:
perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN' < "$file"สำหรับท่อชื่อเราได้เห็นว่าบางระบบ (AIX, Solaris, HP / UX อย่างน้อย) ทำให้ปริมาณของข้อมูลในบัฟเฟอร์ท่อที่มีอยู่ใน'sstat() st_sizeบางคน (เช่น Linux หรือ FreeBSD) ทำไม่ได้
อย่างน้อยใน Linux คุณสามารถใช้FIONREAD ioctl()หลังจากเปิดไพพ์ (ในโหมดอ่าน + เขียนเพื่อหลีกเลี่ยงการแฮงค์):
fuser -s -- "$fifo_file" &&
perl -le 'require "sys/ioctl.ph";
ioctl(STDIN, &FIONREAD, $n) or die$!;
print unpack "L", $n' <> "$fifo_file"
อย่างไรก็ตามโปรดทราบว่าแม้ว่าจะไม่ได้อ่านเนื้อหาของไปป์ แต่การเปิดไปที่ไปป์ที่ตั้งชื่อที่นี่ยังคงมีผลข้างเคียง เราใช้fuserในการตรวจสอบก่อนว่ากระบวนการบางอย่างมีท่อที่เปิดอยู่แล้วเพื่อบรรเทา แต่ก็ไม่สามารถจะเข้าใจผิดได้เพราะfuserอาจไม่สามารถตรวจสอบกระบวนการทั้งหมดได้
ตอนนี้เราได้พิจารณาขนาดของข้อมูลหลักที่เกี่ยวข้องกับไฟล์เท่านั้น ไม่คำนึงถึงขนาดของข้อมูลเมตาและโครงสร้างพื้นฐานที่สนับสนุนทั้งหมดที่จำเป็นสำหรับการจัดเก็บไฟล์นั้น
แอตทริบิวต์ inode อีกกลับโดยเป็นstat() st_blocksนั่นคือจำนวนบล็อก 512 ไบต์ที่ใช้เพื่อเก็บข้อมูลของไฟล์ (และบางครั้งข้อมูลเมตาของมันบางอย่างเช่นแอตทริบิวต์เพิ่มเติมบนระบบไฟล์ ext4 บน Linux) ไม่รวม inode เองหรือรายการในไดเรกทอรีที่ไฟล์เชื่อมโยง
ขนาดและการใช้งานดิสก์ไม่จำเป็นต้องเกี่ยวข้องอย่างแน่นหนาเช่นการบีบอัดความกระจัดกระจาย (บางครั้งเมทาดาทา) โครงสร้างพื้นฐานพิเศษเช่นบล็อกทางอ้อมในระบบไฟล์บางระบบมีอิทธิพลในระยะหลัง
โดยทั่วไปจะduใช้ในการรายงานการใช้ดิสก์ คำสั่งส่วนใหญ่ที่แสดงด้านบนจะสามารถรับข้อมูลนั้นได้
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'POSIXLY_CORRECT=1 du -s -- "$file" (ไม่ใช่สำหรับไดเรกทอรีที่จะรวมการใช้งานดิสก์ของไฟล์ภายใน)find -- "$file" -printf '%b\n'zstat -L +block -- $filestat -c %b -- "$file"stat -f %b -- "$file"perl -le 'print((lstat shift)[12])' -- "$file"wc -cใช้fstatแล้วอ่านค่าสูงสุดถึงst_blksizeไบต์สุดท้าย เห็นได้ชัดว่าเป็นเพราะไฟล์ในลินุกซ์/procและ/sysยกตัวอย่างเช่นมีขนาดสถิติว่าเป็นเพียงตัวอย่าง เป็นการดีสำหรับความถูกต้อง แต่ไม่ดีถ้าจุดสิ้นสุดของไฟล์อยู่บนดิสก์และไม่อยู่ในหน่วยความจำ (โดยเฉพาะถ้าใช้กับไฟล์จำนวนมากในลูป) และแย่มากหากไฟล์ถูกย้ายไปยังพื้นที่จัดเก็บเทปใกล้ไลน์หรือเช่นระบบไฟล์โปร่งใสการคลายการบีบอัดของ FUSE
ls -go file | awk '{print $3}'
-goเป็น SysV พวกเขาจะไม่ทำงานกับ BSD (เป็นทางเลือก (XSI) ใน POSIX) คุณต้องการด้วยls -god file | awk '{print $3; exit}'( -dเพื่อให้สามารถทำงานกับไดเรกทอรีexitสำหรับ symlink ด้วยการขึ้นบรรทัดใหม่ในเป้าหมาย) ปัญหาเกี่ยวกับไฟล์อุปกรณ์ยังคงอยู่
wc -cจะรายงานจำนวนไบต์
สคริปต์นี้รวมหลายวิธีในการคำนวณขนาดไฟล์:
(
du --apparent-size --block-size=1 "$file" 2>/dev/null ||
gdu --apparent-size --block-size=1 "$file" 2>/dev/null ||
find "$file" -printf "%s" 2>/dev/null ||
gfind "$file" -printf "%s" 2>/dev/null ||
stat --printf="%s" "$file" 2>/dev/null ||
stat -f%z "$file" 2>/dev/null ||
wc -c <"$file" 2>/dev/null
) | awk '{print $1}'
สคริปต์ทำงานบนระบบ Unix จำนวนมากรวมถึง Linux, BSD, OSX, Solaris, SunOS และอื่น ๆ
ขนาดไฟล์แสดงจำนวนไบต์ มันเป็นขนาดที่ชัดเจนซึ่งเป็นไบต์ไฟล์ที่ใช้บนดิสก์ทั่วไปโดยไม่มีการบีบอัดพิเศษหรือพื้นที่เบาบางพิเศษหรือบล็อกที่ไม่ได้ปันส่วน ฯลฯ
สคริปต์นี้มีเวอร์ชันการผลิตพร้อมความช่วยเหลือเพิ่มเติมและตัวเลือกเพิ่มเติมที่นี่: https://github.com/SixArm/file-size
สถิติดูเหมือนว่าจะทำสิ่งนี้ด้วยการเรียกระบบน้อยที่สุด:
$ 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
ls -l filename จะให้ข้อมูลมากมายเกี่ยวกับไฟล์รวมถึงขนาดไฟล์สิทธิ์และเจ้าของไฟล์
ขนาดไฟล์ในคอลัมน์ที่ห้าและแสดงเป็นไบต์ ในตัวอย่างด้านล่างขนาดไฟล์อยู่ภายใต้ 2KB:
-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php
แก้ไข:เห็นได้ชัดว่าไม่น่าเชื่อถือเท่าstatคำสั่ง
ls -lและstatคำสั่งให้ข้อมูลขนาดที่เชื่อถือได้ ฉันไม่พบการอ้างอิงใด ๆ ที่ตรงกันข้าม ls -sจะให้ขนาดในจำนวนบล็อก
du filename จะบอกให้คุณใช้งานดิสก์เป็นไบต์
ฉันชอบdu -h filenameซึ่งจะทำให้คุณมีขนาดในรูปแบบที่มนุษย์อ่านได้
duขนาดนี้พิมพ์ออกมาเป็นบล็อก 1024 ไบต์ไม่ใช่จำนวนไบต์ที่เรียบง่าย
duให้เอาต์พุตในหน่วย 512- ไบต์ GNU duใช้ kibibytes แทนเว้นแต่จะเรียกด้วยPOSIXLY_CORRECTในสภาพแวดล้อมของมัน
สร้างฟังก์ชั่นยูทิลิตี้ขนาดเล็กในเชลล์สคริปต์ของคุณที่คุณสามารถมอบหมายให้
ตัวอย่าง
#! /bin/sh -
# vim: set ft=sh
# size utility that works on GNU and BSD systems
size(){
case $(uname) in
(Darwin | *BSD*)
stat -Lf %z -- "$1";;
(*) stat -c %s -- "$1"
esac
}
for f do
printf '%s\n' "$f : $(gzip < "$f" | wc -c) bytes (versus $(size "$f") bytes)"
done
จากข้อมูลจากคำตอบของ @ Stéphane Chazelas
gzip -v < file > /dev/nullเพื่อตรวจสอบความสามารถในการบีบอัดไฟล์
caseคำสั่ง caseเป็นโครงสร้าง Bourne / POSIX เพื่อทำการจับคู่รูปแบบ [[...]]คือ ksh / bash / zsh เท่านั้น (พร้อมชุดรูปแบบ)
ฉันพบสายการบิน AWK 1 และมีข้อบกพร่อง แต่ฉันแก้ไข ฉันยังเพิ่มใน PetaBytes หลังจาก TeraBytes
FILE_SIZE=234234 # FILESIZE IN BYTES
FILE_SIZE=$(echo "${FILE_SIZE}" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }')
เมื่อพิจารณาจากสถิติไม่ได้อยู่ในทุกระบบคุณสามารถใช้โซลูชั่น AWK ได้เกือบทุกครั้ง ตัวอย่าง; ราสเบอร์รี่ Pi ไม่ได้มีสถิติแต่มันก็ไม่ได้มีawk
อีกวิธีหนึ่งที่สอดคล้องกับ POSIX คือการใช้awkกับlength()ฟังก์ชันที่ส่งคืนความยาวเป็นอักขระในแต่ละบรรทัดของไฟล์อินพุตโดยไม่รวมอักขระบรรทัดใหม่ ดังนั้นโดยการทำ
awk '{ sum+=length } END { print sum+NR }' file
เรามั่นใจว่าNRเพิ่มเข้าไปsumดังนั้นจึงส่งผลให้จำนวนตัวอักษรทั้งหมดและจำนวนบรรทัดใหม่ทั้งหมดที่พบในไฟล์ length()ฟังก์ชั่นในการawkใช้เวลาโต้แย้งซึ่งโดยวิธีการเริ่มต้นของlength($0)ซึ่งเป็นสายทั้งในปัจจุบัน
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'ควรพิมพ์ 3 แต่พิมพ์ 4
ฉันชอบตัวเลือก wc ด้วยตัวเอง จับคู่กับ 'bc' คุณจะได้รับตำแหน่งทศนิยมตามที่คุณต้องการ
ฉันต้องการปรับปรุงสคริปต์ที่ทำให้คอลัมน์ 'ขนาดไฟล์' ของคำสั่ง 'ls -alh' น่าตกใจ ฉันไม่ต้องการเพียงแค่ขนาดไฟล์จำนวนเต็มและทศนิยมสองตำแหน่งดูเหมือนจะเหมาะสมดังนั้นหลังจากอ่านการสนทนานี้ฉันก็มาพร้อมกับรหัสด้านล่าง
ฉันขอแนะนำให้แบ่งบรรทัดที่อัฒภาคหากคุณรวมไว้ในสคริปต์
file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"
สคริปต์ของฉันชื่อgpflสำหรับ "รับความยาวไฟล์รูปภาพ" ฉันใช้มันหลังจากทำการmogrifyในไฟล์ใน imagemagick ก่อนที่จะเปิดหรือโหลดรูปภาพใน GUI jpeg viewer อีกครั้ง
ฉันไม่รู้ว่าอัตรานี้เป็น "คำตอบ" อย่างไรเนื่องจากยืมมาจากสิ่งที่เสนอและพูดคุยกันมากแล้ว ดังนั้นฉันจะทิ้งมันไว้ที่นั่น
BZT
wcอ่านบล็อกสุดท้ายของไฟล์ในกรณีที่stat.st_sizeเป็นเพียงการประมาณ (เช่น Linux /procและ/sysไฟล์) ฉันเดาว่าพวกเขาตัดสินใจที่จะไม่แสดงความคิดเห็นหลักที่ซับซ้อนมากขึ้นเมื่อพวกเขาเพิ่มตรรกะลงไปสองสามบรรทัด: lingrok.org/xref/coreutils/src/wc.c#246
วิธีที่เร็วและง่ายที่สุด (IMO) คือ:
bash_var=$(stat -c %s /path/to/filename)
duและwcคำตอบที่ควรมีข้อจำกัดความรับผิดชอบไม่เคยทำในชีวิตจริง ฉันเพิ่งใช้คำตอบของฉันในแอปพลิเคชันในชีวิตจริงคืนนี้และคิดว่ามันเป็นการแบ่งปันที่คุ้มค่า ผมคิดว่าเราทุกคนมีความคิดเห็นของเราshrugs