ฉันจะรับขนาดไฟล์ในสคริปต์ทุบตีได้อย่างไร
ฉันจะกำหนดสิ่งนี้ให้กับตัวแปร 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
มีwc
builtin (หากคุณเปิดใช้งานคุณยังสามารถเรียกใช้เป็น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
stat
builtin (ตอนนี้เรียกอีกอย่างว่า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 -- $file
stat -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