Làm cách nào tôi có thể nhận được kích thước của tệp trong tập lệnh bash?


246

Làm cách nào tôi có thể nhận được kích thước của tệp trong tập lệnh bash?

Làm thế nào để tôi gán nó cho một biến bash để tôi có thể sử dụng nó sau này?



1
Ghép nối này với pvcatcho một lệnh sao chép hiển thị tiến trình và ETA :)
sudo

stat -c% s file.name
neverMind9

Câu trả lời:


242

Đặt cược tốt nhất của bạn nếu trên một hệ thống GNU:

stat --printf="%s" file.any

Từ người đàn ông stat :

Tổng kích thước% s, tính bằng byte

Trong một tập lệnh bash:

#!/bin/bash
FILENAME=/home/heiko/dummy/packages.txt
FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."

LƯU Ý: xem câu trả lời của @ chbrown để biết cách sử dụng stat trong thiết bị đầu cuối trên Mac OS X.


7
@ h ámed85 statlà cách đơn giản nhất, giả sử bạn đang sử dụng Linux hoặc Cygwin ( statkhông phải là tiêu chuẩn). wc -ctheo đề xuất của Eugéne là hàng xách tay.
Gilles

2
stat: illegal option -- c
Iulian Onofrei

stat --printf="%s" file.txtkhông xuất bất cứ thứ gì trên Debian Jessie ...
woohoo

5
Trên MacOS, công việc này hoạt động:stat -f%z myfile.tar
ccpizza

2
@woohoo Lời nhắc của bạn ghi đè lên đầu ra. man statnói rằng --printf bỏ qua dòng mới. Sử dụng --formathoặc -cđể xem đầu ra. Có được cái nhìn sâu sắc hơn bằng cách so sánh stat --printf="%s" file.any | xxd -vớistat -c "%s" file.any | xxd -
cháu

92
file_size_kb=`du -k "$filename" | cut -f1`

Vấn đề với việc sử dụng statlà nó là một phần mở rộng GNU (Linux). du -kcut -f1được chỉ định bởi POSIX và do đó có thể di chuyển tới bất kỳ hệ thống Unix nào.

Solaris, ví dụ, tàu có bash nhưng không có stat. Vì vậy, đây không hoàn toàn là giả thuyết.

lscó một vấn đề tương tự ở chỗ định dạng chính xác của đầu ra không được chỉ định, do đó việc phân tích cú pháp đầu ra của nó không thể được thực hiện một cách hợp lý. du -hcũng là một phần mở rộng GNU.

Bám sát các cấu trúc di động nếu có thể, và bạn sẽ làm cho cuộc sống của ai đó dễ dàng hơn trong tương lai. Có lẽ là của riêng bạn.


48
dukhông cho kích thước của tệp, nó cho biết dung lượng tệp sử dụng là bao nhiêu, khác nhau một cách tinh tế (thường kích thước được báo cáo dulà kích thước của tệp được làm tròn đến số khối gần nhất, trong đó một khối thường là 512B hoặc 1kB hoặc 4kB).
Gilles

7
@Gilles, các tệp thưa thớt (tức là những tệp có lỗ hổng trong chúng) báo cáo ít hơn độ dài.
vonbrand

5
Điều này, với --byteshoặc -bthay vì -k, nên là câu trả lời được chấp nhận.
Amedee Van Gasse

1
Các -h( "con người") tùy chọndu sẽ tạo ra câu trả lời thích hợp nhất cho trường hợp tổng quát: file_size=`du -h "$filename" | cut -f1, vì nó sẽ hiển thị K (kilobyte), M (MB) hoặc G (Gigabyte) cho phù hợp.
fralau

1
@fralau: OP muốn "gán giá trị này cho biến bash để họ có thể sử dụng nó sau", do đó nhiều khả năng họ muốn có một giá trị số thực tế, không phải là xấp xỉ có thể đọc được. Ngoài ra, -hlà một phần mở rộng GNU; nó không chuẩn
Nemo

74

Bạn cũng có thể sử dụng lệnh "đếm từ" ( wc):

wc -c "$filename" | awk '{print $1}'

Vấn đề wclà nó sẽ thêm tên tệp và thụt đầu ra. Ví dụ:

$ wc -c somefile.txt
    1160 somefile.txt

Nếu bạn muốn tránh xâu chuỗi một ngôn ngữ được giải thích đầy đủ hoặc trình chỉnh sửa luồng chỉ để lấy số lượng kích thước tệp, chỉ cần chuyển hướng đầu vào từ tệp để wckhông bao giờ thấy tên tệp:

wc -c < "$filename"

Hình thức cuối cùng này có thể được sử dụng với sự thay thế lệnh để dễ dàng lấy giá trị mà bạn đang tìm kiếm như một biến shell, như được đề cập bởi Gilles dưới đây.

size="$(wc -c <"$filename")"

30
wc -c <"$FILENAME"Do đó, cho kích thước không có hành trình khác size=$(wc -c <"$FILENAME").
Gilles

6
Chỉ còn một điểm nữa: Tôi vừa thử nghiệm nó và wc -c < filedường như rất nhanh, ít nhất là trên OS X. Tôi đoán rằng wc có bộ não để cố gắng thống kê tệp nếu chỉ -c được chỉ định.
Edward Falk

4
@EdwardFalk: GNU wc -csử dụng fstat, nhưng sau đó tìm đến khối thứ hai của tệp và đọc các st_blksizebyte cuối cùng . Rõ ràng điều này là do các tệp trong Linux /proc/sysví dụ có kích thước chỉ gần đúngwcmuốn báo cáo kích thước thực tế, không phải kích thước được báo cáo theo thống kê. Tôi đoán sẽ là lạ wc -ckhi báo cáo kích thước khác hơn wc, nhưng không nên đọc dữ liệu từ tệp nếu đó là tệp đĩa bình thường và không có trong bộ nhớ. Hoặc tệ hơn, lưu trữ băng gần tuyến ...
Peter Cordes

1
Có vẻ như printfvẫn thấy vết lõm, ví dụ printf "Size: $size"-> size: <4 spaces> 54339. Mặt khác echobỏ qua khoảng trắng. Bất kỳ cách nào để làm cho nó phù hợp?
Eugene Kulabuhov

2
@keithpjcar: Bằng cách gọi fstat. Hãy thử chạy strace wc -c </etc/passwdvà bạn có thể thấy những gì nó đang làm.
Nemo

48

BSD (Mac OS X's) statcó cờ đối số định dạng khác nhau và các công cụ xác định trường khác nhau. Từ man stat(1):

  • -f format: Hiển thị thông tin bằng cách sử dụng định dạng được chỉ định. Xem phần FORMATS để biết mô tả về các định dạng hợp lệ.
  • ... phần ĐỊNH DẠNG ...
  • z: Kích thước của tệp theo byte.

Vì vậy, tất cả cùng nhau bây giờ:

stat -f%z myfile1.txt

28

Phụ thuộc vào những gì bạn có nghĩa là theo kích thước .

size=$(wc -c < "$file")

sẽ cung cấp cho bạn số byte có thể được đọc từ tệp. IOW, đó là kích thước của nội dung của tập tin. Tuy nhiên, nó sẽ đọc nội dung của tệp (trừ khi tệp là tệp thông thường hoặc liên kết tượng trưng đến tệp thông thường trong hầu hết các wctriển khai dưới dạng tối ưu hóa). Điều đó có thể có tác dụng phụ. Ví dụ, đối với một đường ống có tên, những gì đã đọc không còn có thể được đọc lại và đối với những thứ như /dev/zerohoặc /dev/randomcó kích thước vô hạn, sẽ mất một thời gian. Điều đó cũng có nghĩa là bạn cần có readquyền đối với tệp và dấu thời gian truy cập cuối cùng của tệp có thể được cập nhật.

Đó là tiêu chuẩn và di động, tuy nhiên lưu ý rằng một số wctriển khai có thể bao gồm các khoảng trống hàng đầu trong đầu ra đó. Một cách để loại bỏ chúng là sử dụng:

size=$(($(wc -c < "$file")))

hoặc để tránh lỗi về biểu thức số học trống trong dashhoặc yashkhi wckhông tạo ra đầu ra (như khi tệp không thể mở được):

size=$(($(wc -c < "$file") +0))

ksh93đã wcdựng sẵn (miễn là bạn kích hoạt nó, bạn cũng có thể gọi nó dưới dạng command /opt/ast/bin/wc), điều này làm cho nó hiệu quả nhất đối với các tệp thông thường trong trình bao đó.

Các hệ thống khác nhau có một lệnh được gọi là statgiao diện cho các cuộc gọi stat()hoặc lstat()hệ thống.

Những thông tin báo cáo được tìm thấy trong inode. Một trong những thông tin đó là st_sizethuộc tính. Đối với các tệp thông thường, đó là kích thước của nội dung (có thể đọc được bao nhiêu dữ liệu từ nội dung đó nếu không có lỗi (đó là điều mà hầu hết các wc -ctriển khai sử dụng trong tối ưu hóa của chúng)). Đối với các liên kết tượng trưng, ​​đó là kích thước tính theo byte của đường dẫn đích. Đối với các đường ống được đặt tên, tùy thuộc vào hệ thống, đó là 0 hoặc số byte hiện có trong bộ đệm ống. Tương tự đối với các thiết bị khối trong đó tùy thuộc vào hệ thống, bạn nhận được 0 hoặc kích thước tính theo byte của bộ lưu trữ bên dưới.

Bạn không cần quyền đọc tệp để có được thông tin đó, chỉ có quyền tìm kiếm vào thư mục mà nó được liên kết đến.

Theo thứ tự thời gian, có:

  • IRIXstat (90 giây ):

    stat -qLs -- "$file"

    trả về st_sizethuộc tính của $file( lstat()) hoặc:

    stat -s -- "$file"

    tương tự ngoại trừ khi nào $filelà một liên kết tượng trưng trong trường hợp đó là st_sizetệp sau khi phân giải symlink.

  • zsh statdựng sẵn (bây giờ còn được gọi là zstat) trong zsh/statmô-đun (được tải với zmodload zsh/stat) (1997):

    stat -L +size -- $file # st_size of file
    stat +size -- $file    # after symlink resolution

    hoặc để lưu trữ trong một biến:

    stat -L -A size +size -- $file

    rõ ràng, đó là hiệu quả nhất trong vỏ đó.

  • GNUstat (2001); cũng trong BusyBox stattừ năm 2005 (được sao chép từ GNU stat):

    stat -c %s -- "$file"  # st_size of file
    stat -Lc %s -- "$file" # after symlink resolution

    (lưu ý ý nghĩa của -Lđảo ngược so với IRIX hoặc zsh stat.

  • BSDstat (2002):

    stat -f %z -- "$file"  # st_size of file
    stat -Lf %z -- "$file" # after symlink resolution

Hoặc bạn có thể sử dụng chức năng stat()/ lstat()của một số ngôn ngữ kịch bản như perl:

perl -le 'print((lstat shift)[7])' -- "$file"

AIX cũng có một istatlệnh sẽ loại bỏ tất cả thông tin stat()(không lstat(), vì vậy sẽ không hoạt động trên các liên kết tượng trưng) và bạn có thể xử lý hậu kỳ với, ví dụ:

LC_ALL=C istat "$file" | awk 'NR == 4 {print $5}'

(cảm ơn @JeffSchaller vì đã giúp tìm ra các chi tiết ).

Trong tcsh:

@ size = -Z $file:q

(kích thước sau khi phân giải symlink)

Rất lâu trước khi GNU giới thiệu statlệnh của mình , điều tương tự có thể đạt được với findlệnh GNU với -printfvị từ của nó (đã có vào năm 1991):

find -- "$file" -prune -printf '%s\n'    # st_size of file
find -L -- "$file" -prune -printf '%s\n' # after symlink resolution

Tuy nhiên, một vấn đề là nó không hoạt động nếu $filebắt đầu bằng -hoặc là một findvị ngữ (như !, (...).

Lệnh tiêu chuẩn để có được stat()/ lstat()thông tin là ls.

POSIXly, bạn có thể làm:

LC_ALL=C ls -dn -- "$file" | awk '{print $5; exit}'

và thêm -Lcho cùng sau khi giải quyết symlink. Điều đó không hoạt động đối với các tệp thiết bị mặc dù trường thứ 5 là số chính của thiết bị thay vì kích thước.

Đối với các thiết bị khối, các hệ thống stat()trả về 0 cho st_size, thường có các API khác để báo cáo kích thước của thiết bị khối. Chẳng hạn, Linux có BLKGETSIZE64 ioctl()và hầu hết các bản phân phối Linux hiện có một blockdevlệnh có thể sử dụng nó:

blockdev --getsize64 -- "$device_file"

Tuy nhiên, bạn cần có quyền đọc tệp thiết bị cho điều đó. Thông thường có thể lấy kích thước bằng các phương tiện khác. Ví dụ: (vẫn trên Linux):

lsblk -bdno size -- "$device_file"

Nên làm việc ngoại trừ các thiết bị trống.

Một cách tiếp cận mà làm việc cho tất cả seekable file (để bao gồm các file thường xuyên, hầu hết các thiết bị khối và một số thiết bị ký tự) là để mở các tập tin và tìm cách cuối cùng:

  • Với zsh(sau khi tải zsh/systemmô-đun):

    {sysseek -w end 0 && size=$((systell(0)))} < $file
  • Với ksh93:

    < "$file" <#((size=EOF))

    hoặc là

    { size=$(<#((EOF))); } < "$file"
  • với perl:

    perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN' < "$file"

Đối với các đường ống được đặt tên, chúng tôi đã thấy rằng một số hệ thống (ít nhất là AIX, Solaris, HP / UX) tạo ra lượng dữ liệu trong bộ đệm ống có sẵn trong stat()các st_size. Một số (như Linux hoặc FreeBSD) thì không.

Trên Linux ít nhất, bạn có thể sử dụng FIONREAD ioctl()sau khi mở đường ống (ở chế độ đọc + ghi để tránh bị treo):

fuser -s -- "$fifo_file" && 
  perl -le 'require "sys/ioctl.ph";
            ioctl(STDIN, &FIONREAD, $n) or die$!;
            print unpack "L", $n' <> "$fifo_file"

Tuy nhiên lưu ý rằng mặc dù nó không đọc nội dung của đường ống, nhưng việc mở đường ống có tên ở đây vẫn có thể có tác dụng phụ. Trước tiên, chúng tôi đang sử dụng fuserđể kiểm tra xem một số quy trình đã có đường ống mở để giảm bớt điều đó nhưng điều đó không thể đánh lừa được vì fusercó thể không thể kiểm tra tất cả các quy trình.

Bây giờ, cho đến nay chúng tôi chỉ xem xét kích thước của dữ liệu chính được liên kết với các tệp. Điều đó không tính đến kích thước của siêu dữ liệu và tất cả các cơ sở hạ tầng hỗ trợ cần thiết để lưu trữ tệp đó.

Một thuộc tính inode khác được trả về stat()st_blocks. Đó là số khối 512 byte được sử dụng để lưu trữ dữ liệu của tệp (và đôi khi một số siêu dữ liệu của nó như các thuộc tính mở rộng trên hệ thống tệp ext4 trên Linux). Điều đó không bao gồm chính inode hoặc các mục trong thư mục mà tệp được liên kết đến.

Kích thước và mức độ sử dụng đĩa không nhất thiết liên quan chặt chẽ như nén, thưa thớt (đôi khi là một số siêu dữ liệu), cơ sở hạ tầng bổ sung như các khối gián tiếp trong một số hệ thống tệp có ảnh hưởng đến sau này.

Đó thường là những gì dusử dụng để báo cáo việc sử dụng đĩa. Hầu hết các lệnh được liệt kê ở trên sẽ có thể giúp bạn có được thông tin đó.

  • POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
  • POSIXLY_CORRECT=1 du -s -- "$file" (không dành cho các thư mục bao gồm việc sử dụng đĩa của các tệp trong đó).
  • GNU find -- "$file" -printf '%b\n'
  • zstat -L +block -- $file
  • GNU stat -c %b -- "$file"
  • BSD stat -f %b -- "$file"
  • perl -le 'print((lstat shift)[12])' -- "$file"

rõ ràng câu trả lời toàn diện và thông tin nhất. cảm ơn bạn. tôi có thể sử dụng điều này để tạo các tập lệnh bash đa nền tảng bằng cách sử dụng thông tin thống kê BSD và GNU
oligofren

1
Thực tế thú vị: GNU coreutils wc -csử dụng fstat, nhưng sau đó đọc các st_blksizebyte cuối cùng . Rõ ràng điều này là do các tệp trong Linux /proc/sysví dụ có kích thước chỉ tương đương . Điều này tốt cho tính chính xác, nhưng sẽ tệ nếu phần cuối của tệp nằm trên đĩa chứ không phải trong bộ nhớ (đặc biệt nếu được sử dụng trên nhiều tệp trong một vòng lặp). Và rất tệ nếu tệp được di chuyển sang lưu trữ băng gần dòng , hoặc ví dụ hệ thống tệp giải nén trong suốt FUSE.
Peter Cordes

điều này cũng không hiệu quảls -go file | awk '{print $3}'
Steven Penny

@StevenPenny đó -gosẽ là những người SysV, họ sẽ không hoạt động trên BSD (tùy chọn (XSI) trong POSIX). Bạn cũng cần ls -god file | awk '{print $3; exit}'( -dđể nó hoạt động trên các thư mục, exitcho các liên kết tượng trưng với dòng mới trong mục tiêu). Các vấn đề với tập tin thiết bị cũng vẫn còn.
Stéphane Chazelas

1
@ α Unixsнιη API Unix không phân biệt giữa tệp văn bản và tệp nhị phân. Đó là tất cả các chuỗi byte. Một số ứng dụng có thể muốn diễn giải các byte đó thành văn bản nhưng rõ ràng không phải là wc -cbáo cáo số lượng byte.
Stéphane Chazelas

22

Kịch bản này kết hợp nhiều cách để tính kích thước tệp:

(
  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}'

Kịch bản hoạt động trên nhiều hệ thống Unix bao gồm Linux, BSD, OSX, Solaris, SunOS, v.v.

Kích thước tệp hiển thị số byte. Đó là kích thước rõ ràng, là byte mà tệp sử dụng trên một đĩa điển hình, không có nén đặc biệt, hoặc các vùng thưa đặc biệt hoặc các khối không được phân bổ, v.v.

Kịch bản này có phiên bản sản xuất với nhiều trợ giúp hơn và nhiều tùy chọn hơn tại đây: https://github.com/SixArm/file-size


9

stat xuất hiện để làm điều này với các cuộc gọi hệ thống ít nhất:

$ 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

8

ls -l filename sẽ cung cấp cho bạn nhiều thông tin về một tệp, bao gồm kích thước tệp, quyền và chủ sở hữu.

Kích thước tệp trong cột thứ năm và được hiển thị theo byte. Trong ví dụ dưới đây, kích thước tệp chỉ dưới 2KB:

-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php

Chỉnh sửa: Điều này rõ ràng là không đáng tin cậy như statlệnh.


Tôi nghĩ rằng cả hai ls -lstatlệnh cho thông tin kích thước đáng tin cậy. Tôi không tìm thấy bất kỳ tài liệu tham khảo ngược lại. ls -ssẽ cho kích thước về số lượng khối.
dabest1

2
@ dabest1 không đáng tin theo nghĩa là trong một unix khác, đầu ra của chúng có thể khác nhau (và trong một số unix đó là).
Eugene Bujak

Có, IIRC, Solaris không hiển thị tên nhóm theo mặc định, dẫn đến ít cột hơn trong đầu ra.
Edward Falk

Vì kích thước là số thuần túy, được bao quanh bởi khoảng trắng và năm ngày là số thuần túy, theo định dạng xác định, có thể sử dụng biểu thức chính quy để coi người dùng + chủ sở hữu là một trường, cho dù nhóm có hay không. (một bài tập cho người đọc!)
MikeW

5

du filename sẽ cho bạn biết việc sử dụng đĩa theo byte.

Tôi thích du -h filename, cung cấp cho bạn kích thước trong một định dạng có thể đọc được con người.


2
đó hoặc stat -c "%s";)

1
Hương vị này duin ra kích thước trong các khối 1024 byte, không phải là số byte đơn giản.
Peter Lyons

Lưu ý rằng tiêu chuẩn ducung cấp một đầu ra với số lượng đơn vị 512 byte. GNU dusử dụng kibibytes thay vì trừ khi được gọi POSIXLY_CORRECTtrong môi trường của nó.
Stéphane Chazelas

1
Đối với các tệp của thư mục loại , điều đó cho phép sử dụng đĩa của thư mục mà còn cho tất cả các tệp khác trong (đệ quy).
Stéphane Chazelas

3

Tạo các hàm tiện ích nhỏ trong tập lệnh shell của bạn mà bạn có thể ủy quyền.

Thí dụ

#! /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

Dựa trên thông tin từ câu trả lời của @ Stéphane Chazelas.


Xem thêm gzip -v < file > /dev/nullđể kiểm tra khả năng nén của tệp.
Stéphane Chazelas

@ StéphaneChazelas không chắc chắn nếu tôi nghĩ đó là một cải tiến. những tuyên bố trường hợp có thể dễ dàng đưa noobs ra; Tôi chắc chắn không bao giờ nhớ làm thế nào để làm cho chúng đúng :-) là những câu lệnh tình huống vốn dễ mang theo hơn kể từ khi bạn làm điều đó? tôi thấy điểm khi có nhiều hơn hai trường hợp, nhưng nếu không thì ... +
oligofren

1
Tôi cho rằng đó cũng là vấn đề của hương vị, nhưng đây là trường hợp điển hình mà bạn muốn sử dụng một casetuyên bố. caselà cấu trúc Bourne / POSIX để thực hiện khớp mẫu. [[...]]chỉ ksh / bash / zsh (có biến thể).
Stéphane Chazelas

2

Tôi đã tìm thấy một lớp lót AWK 1, và nó có một lỗi nhưng tôi đã sửa nó. Tôi cũng đã thêm vào PetaBytes sau 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] }')

Xem xét stat không có trên mọi hệ thống, bạn hầu như luôn có thể sử dụng giải pháp AWK. Thí dụ; Raspberry Pi không có stat nhưng nó có awk .


1
Hoàn toàn KHÔNG phải những gì OP yêu cầu, nhưng công việc nhỏ bé tốt đẹp.
Spellweaver Gypsy

0

Một cách khác tuân thủ POSIX sẽ là sử dụng awkvới length()chức năng của nó trả về độ dài, tính bằng ký tự trên mỗi dòng của tệp đầu vào, ngoại trừ các ký tự dòng mới. Vì vậy, bằng cách làm

awk '{ sum+=length } END { print sum+NR }' file

chúng tôi đảm bảo NRđược thêm vào sum, do đó dẫn đến tổng số ký tự và tổng số dòng mới gặp trong tệp. Các length()chức năng trong awkcó một đối số đó bằng phương tiện mặc định length($0)mà là cho toàn bộ dòng hiện tại.


Không phải nếu dòng cuối cùng không kết thúc trên một dòng mới: printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'nên in 3 nhưng in 4.
Isaac

-1

Tôi thích tùy chọn wc mình. Được kết hợp với 'bc', bạn có thể nhận được số thập phân đến nhiều nơi bạn muốn.

Tôi đang tìm cách cải thiện một tập lệnh mà tôi đã sử dụng cột 'kích thước tệp' của lệnh 'ls -alh'. Tôi không muốn chỉ có kích thước tệp số nguyên và hai số thập phân có vẻ phù hợp, vì vậy sau khi đọc cuộc thảo luận này, tôi đã đưa ra mã dưới đây.

Tôi đề nghị phá vỡ dòng tại dấu chấm phẩy nếu bạn bao gồm điều này trong một kịch bản.

file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"

Kịch bản của tôi được gọi là gpfl , cho "lấy chiều dài tệp hình ảnh." Tôi sử dụng nó sau khi thực hiện một mogrify trên một tệp trong hình ảnh, trước khi mở hoặc tải lại một hình ảnh trong trình xem jpeg GUI.

Tôi không biết mức giá này như là một "câu trả lời" như thế nào vì nó vay mượn nhiều từ những gì đã được cung cấp và thảo luận. Vì vậy, tôi sẽ để nó ở đó.

BZT


1
Tôi thích sử dụng "stat" hoặc "ls". Thông thường tôi không thích sử dụng "wc" để lấy kích thước tệp vì nó thực sự đọc toàn bộ tệp. Nếu bạn có nhiều tệp, hoặc tệp đặc biệt lớn, việc này có thể mất nhiều thời gian. Nhưng giải pháp của bạn là sáng tạo ... + 1.
Kevin Fegan

2
Tôi đồng ý với khái niệm sử dụng "stat" trên "wc" cho kích thước tệp, tuy nhiên nếu bạn sử dụng "wc -c", sẽ không có dữ liệu nào được đọc; thay vào đó lseek sẽ được sử dụng để tìm ra số byte trong một tệp. lingrok.org/xref/coreutils/src/wc.c#228
bbaja42

1
@ bbaja42: lưu ý rằng GNU Coreutils đã wcđọc khối cuối cùng của tệp, trong trường hợp stat.st_sizechỉ là một xấp xỉ (như đối với Linux /proc/syscác tệp). Tôi đoán họ đã quyết định không làm cho bình luận chính trở nên phức tạp hơn khi họ thêm logic đó vào một vài dòng: lingrok.org/xref/coreutils/src/wc.c#246
Peter Cordes

-1

Phương pháp nhanh nhất và đơn giản nhất (IMO) là:

bash_var=$(stat -c %s /path/to/filename)

2
Sau đó, upvote một hoặc nhiều câu trả lời hiện có đề cập đến stat; không cần lặp lại lần nữa ...
Jeff Schaller

1
@JeffSchaller Tôi vừa nêu lên câu trả lời của Stephane theo hướng dẫn của bạn. Tôi nghĩ rằng nó quá phức tạp cho mục đích của tôi. Đó là lý do tại sao tôi đăng câu trả lời đơn giản này cho những tâm hồn thích đầu óc.
WinEunuuchs2Unix

1
Cảm ơn bạn; đó chỉ là ví dụ thứ sáu của câu trả lời "stat" không đơn giản hóa câu hỏi và trả lời này, nhưng muốn khiến người đọc mới tự hỏi "câu trả lời này khác với câu hỏi khác như thế nào?" và dẫn đến nhiều nhầm lẫn thay vì ít hơn.
Jeff Schaller

@JeffSchaller tôi đoán. Nhưng tôi có thể phàn nàn về nhiều điều duwccâu trả lời nên từ chối KHÔNG BAO GIỜ NÀY trong cuộc sống thực. Tôi chỉ sử dụng câu trả lời của mình trong một ứng dụng thực tế tối nay và nghĩ rằng nó đáng để chia sẻ. Tôi đoán tất cả chúng ta có ý kiến ​​của chúng tôi nhún vai .
WinEunuuchs2Unix
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.