쉘에서 파일 크기(바이트 단위)를 얻는 이식 가능한 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1815329

  •  06-07-2019
  •  | 
  •  

문제

Linux에서는 다음을 사용합니다. stat --format="%s" FILE, 그러나 내가 액세스할 수 있는 Solaris에는 stat 명령이 없습니다.그러면 무엇을 사용해야 합니까?

저는 Bash 스크립트를 작성하고 있는데 실제로 시스템에 새로운 소프트웨어를 설치할 수 없습니다.

나는 이미 다음을 사용하는 것을 고려했습니다.

perl -e '@x=stat(shift);print $x[7]' FILE

또는:

ls -nl FILE | awk '{print $5}'

하지만 둘 중 어느 것도 타당해 보이지 않습니다. 단지 파일 크기를 얻기 위해 Perl을 실행한다고요?아니면 동일한 작업을 수행하기 위해 2개의 명령을 실행하시겠습니까?

도움이 되었습니까?

해결책

wc -c < filename (단어 수의 줄임말, -c 바이트 수를 인쇄합니다)은 이식 가능합니다. POSIX 해결책.일부 공백이 앞에 추가될 수 있으므로(Solaris의 경우) 출력 형식만 플랫폼 전체에서 동일하지 않을 수 있습니다.

입력 리디렉션을 생략하지 마십시오.파일이 인수로 전달되면 파일 이름은 바이트 수 뒤에 인쇄됩니다.

바이너리 파일에서는 작동하지 않을까 걱정했는데 Linux와 Solaris 모두에서 잘 작동합니다.당신은 그것을 시도 할 수 있습니다 wc -c < /usr/bin/wc.게다가 POSIX 유틸리티는 바이너리 파일 처리 보장, 달리 명시적으로 지정하지 않는 한.

다른 팁

나는 크기를 표시하기 위해 내 자신의 프로그램 (정말 작은)을 작성하게되었습니다. 자세한 내용 : http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html

일반적인 Linux 도구에서 제 생각에 가장 깨끗한 두 가지 방법은 다음과 같습니다.

$ stat -c %s /usr/bin/stat
50000

$ wc -c < /usr/bin/wc
36912

그러나 파일 크기를 얻기 위해 매개 변수를 입력하거나 출력을 파이프하고 싶지 않으므로 나만의 BFSize를 사용하고 있습니다.

일지라도 du 일반적으로 디스크 사용을 인쇄하고 실제 데이터 크기가 아닌 GNU Coreutils du 바이트로 파일의 "명백한 크기"를 인쇄 할 수 있습니다.

du -b FILE

그러나 BSD, Solaris, MacOS, ...

마지막으로 LS와 Bash Array 확장을 사용하기로 결정했습니다.

TEMP=( $( ls -ln FILE ) )
SIZE=${TEMP[4]}

정말 좋지는 않지만 적어도 1 개의 포크+exece 만 수행하며 2 차 프로그래밍 언어 (Perl/Ruby/Python/Nothingle)에 의존하지 않습니다.

크로스 플랫폼 가장 빠른 솔루션 (단일 포크 () 만 사용합니다. ls, 실제 캐릭터를 계산하려고 시도하지 않고 불필요한 awk, perl 등을 생성하지 않습니다).

MacOS에서 테스트 된 Linux- Solaris에 대한 약간의 수정이 필요할 수 있습니다.

__ln=( $( ls -Lon "$1" ) )
__size=${__ln[3]}
echo "Size is: $__size bytes"

필요한 경우 단순화하십시오 ls 인수 및 $ {__ ln [3]}의 오프셋을 조정하십시오.

참고 : Symlinks를 따릅니다.

BSD가 있습니다 stat GNU Coreutils와는 다른 옵션이 있지만 유사한 기능.

stat -f %z <file name> 

이것은 작동합니다 맥 OS (10.12에 테스트), freebsd, netbsd 그리고 OpenBsd.

사용하는 경우 find GNU 파일 우틸에서 :

size=$( find . -maxdepth 1 -type f -name filename -printf '%s' )

불행히도, 다른 구현 find 일반적으로 지원하지 않습니다 -maxdepth, 또는 -printf. 이것은 예를 들어 Solaris와 MacOS의 경우입니다 find.

처리할 때 ls -n 출력에서는 이식성이 떨어지는 쉘 배열 대신에 유일한 배열을 형성하고 표준 쉘의 유일한 지역 변수인 위치 인수를 사용할 수 있습니다.스크립트나 함수에 대한 원래 인수를 유지하려면 함수에서 위치 인수 덮어쓰기를 래핑하세요.

getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE

이는 출력을 분할합니다. ln -dn 현재에 따르면 IFS 환경 변수 설정을 통해 이를 위치 인수에 할당하고 다섯 번째 인수를 에코합니다.그만큼 -d 디렉토리가 제대로 처리되고 있는지 확인합니다. -n 와 달리 사용자 및 그룹 이름을 확인할 필요가 없음을 보장합니다. -l.또한 공백이 포함된 사용자 및 그룹 이름은 이론적으로 예상되는 줄 구조를 깨뜨릴 수 있습니다.일반적으로 허용되지 않지만 이 가능성은 여전히 ​​프로그래머를 멈추고 생각하게 만듭니다.

당신이 사용할 수있는 find 명령 일부 파일 세트를 얻으려면 (여기서 온도 파일이 추출됩니다). 그런 다음 사용할 수 있습니다 du 명령은 각 파일의 파일 크기를 사람을 읽을 수있는 양식으로 사용하여 -h 스위치.

find $HOME -type f -name "*~" -exec du -h {} \;

산출:

4.0K    /home/turing/Desktop/JavaExmp/TwoButtons.java~
4.0K    /home/turing/Desktop/JavaExmp/MyDrawPanel.java~
4.0K    /home/turing/Desktop/JavaExmp/Instream.java~
4.0K    /home/turing/Desktop/JavaExmp/RandomDemo.java~
4.0K    /home/turing/Desktop/JavaExmp/Buff.java~
4.0K    /home/turing/Desktop/JavaExmp/SimpleGui2.java~

당신은 첫 번째 perl 예제가 나에게 불합리하게 보이지 않습니다.

이와 같은 이유는 내가 쉘 스크립트를 작성하여 (bash/sh 등) Perl에서 가장 사소한 스크립트를 제외한 모든 글을 쓰는 것으로 마이그레이션 한 이유입니다. 나는 특정 요구 사항에 대해 Perl을 시작해야한다는 것을 알았고, 점점 더 많은 것을했듯이 Perl에 스크립트를 작성하는 것이 더 강력하다는 것을 깨달았습니다 (언어와 광범위한 라이브러리는 다양한 라이브러리를 통해 제공됩니다. CPAN) 그리고 내가 원하는 것을 달성하는보다 효율적인 방법.

다른 쉘 스크립팅 언어 (예 : Python/Ruby)는 의심 할 여지없이 비슷한 시설을 가질 것이며, 목적을 위해이를 평가할 수 있습니다. 나는 그것이 내가 사용하고 친숙한 언어이기 때문에 Perl에 대해서만 논의합니다.

Solaris에 Perl이있는 경우 사용하십시오. 그렇지 않으면, AWK를 가진 LS가 다음 가장 좋은 방법입니다. 통계가 없거나 찾은 곳이 GNU 찾기가 아니기 때문입니다.

내가 사용한 Solaris에는 트릭이 있습니다. 두 개 이상의 파일의 크기를 요청하면 이름이없는 총 크기 만 반환합니다. 두 번째 파일로 /dev /null과 같은 빈 파일을 포함시킵니다.

예를 들어, 명령 fileyouwant /dev /null

LS/WC/etc에 효과가있는 Size Command를 기억할 수 없습니다. 불행히도 테스트 할 Solaris 상자가 없습니다.

Linux에서 사용할 수 있습니다 du -h $FILE, 그것은 Solaris에도 효과가 있습니까?

Du -Ks |를 시도 했습니까? awk '{print $ 1*1024}'. 그것은 단지 작동 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top