특정 파일이 특정 크기일 때만 명령을 실행하는 방법

특정 파일이 특정 크기일 때만 명령을 실행하는 방법

특정 파일이 정의된 크기를 초과하는 경우에만 명령을 실행하는 방법은 무엇입니까? 둘 다 궁극적으로 crontab에서 한 줄의 코드로 실행되어야 합니다.

의사코드:

* * * * * find /cache/myfile.csv -size +5G && echo "file is > 5GB"

답변1

GNU가 있는 경우 해당 옵션을 사용하여 크기를 얻을 stat수 있습니다.--printf

예를 들어

size=$(stat --printf '%s' /cache/myfile.csv)
if [ "$size" -gt 5368709120 ] ; then  # 5 GiB = 5 * 1024 * 1024 * 1024
  echo "file is > 5GB"
fi

man stat자세히보다.


BSD stat(예: FreeBSD 및 Mac)에는 유사한 형식 지정 옵션이 있습니다 -f.

size=$(stat -f '%z' /cache/myfile.csv)

또는 Perl의 내장 stat함수나 -s파일 테스트 연산자를 사용할 수 있습니다(bash의 file test 와 유사 -s하지만 파일이 존재하고 비어 있지 않은 경우 true를 반환하는 대신 파일 크기를 반환합니다). Perl의 stat 함수는 다음 데이터(에서 복사됨)를 포함하는 파일에 대한 메타데이터의 13개 요소 목록(배열)을 반환합니다 perldoc -f stat.

[...] Not all fields are supported on all filesystem types. Here are
the meanings of the fields: 

  0 dev      device number of filesystem
  1 ino      inode number
  2 mode     file mode  (type and permissions)
  3 nlink    number of (hard) links to the file 
  4 uid      numeric user ID of file's owner
  5 gid      numeric group ID of file's owner
  6 rdev     the device identifier (special files only) 
  7 size     total size of file, in bytes
  8 atime    last access time in seconds since the epoch
  9 mtime    last modify time in seconds since the epoch
 10 ctime    inode change time in seconds since the epoch (*)
 11 blksize  preferred I/O size in bytes for interacting with the
             file (may vary from file to file)
 12 blocks   actual number of system-specific blocks allocated
             on disk (often, but not always, 512 bytes each) 

(The epoch was at 00:00 January 1, 1970 GMT.)

필드 7은 우리에게 필요한 필드입니다.

파일 크기를 반환하려면(나중에 쉘 명령이나 스크립트에서 사용하기 위해) 다음을 사용하십시오 stat.

# stat
perl -e 'print scalar((stat(shift))[7])' /cache/myfile.csv

# -s
perl -e 'print -s shift' /cache/myfile.csv

아니면 Perl을 사용하여 모든 작업을 수행할 수 있습니다.

# stat
perl -e 'print "File is > 5 GiB\n" if (stat(shift))[7] > 5*1024*1024*1024' /cache/myfile.csv

# -s
perl -e 'print "File is > 5 GiB\n" if -s shift > 5*1024*1024*1024' /cache/myfile.csv

perldoc -f statand perldoc -f -X(그리고 help testbash에서) 를 참조하세요 .

그런데 Perl의 shift함수는 배열의 첫 번째 요소(기본적으로 @ARGV지정되지 않은 경우 명령줄 인수 배열)를 제거하고 해당 값을 반환합니다. 배열의 모든 요소를 ​​처리하기 위해 루프에서 자주 사용되지만 여기서는 첫 번째 매개변수(파일 이름)에만 관심이 있습니다. perldoc -f shift어휘 범위 및 서브루틴에서의 사용에 대한 참고 사항을 포함한 자세한 내용은 참고자료를 참조하세요.

답변2

파일 크기를 전제 조건으로 사용하려면 다음을 수행하십시오.사용stat또는 find:

[ -n "$(find /cache/myfile.csv -prune -size +5G 2>/dev/null)" ] && echo "file is > 5GB"

또는 대상 명령(여기)이 짧은 경우 "찾기" 섹션 echo에 넣으세요.exec

find /cache/myfile.csv -prune -size +5G -exec echo "file is > 5GB" \;

혹시라도 빠지는 것을 방지하기 위해 디렉토리 형태의 파일입니다 -prune.myfile.csvfind

답변3

셸에서 파일을 처리해야 하는 경우 두 버전 모두 모든 조건이 충족되는 경우에만 셸의 명령을 실행합니다. 파일이고 이름이 지정되었으며 myfile.csv> 5G입니다.

find /cache -name 'myfile.csv' -type f -size +5G -exec bash -c '
    echo "$1 is > 5GB"
' bash {} \;

또는

find /cache -name 'myfile.csv' -type f -size +5G -exec bash -c '
    for file; do echo "$file is > 5GB"; done
' bash {} +

답변4

일부 쉘에는 내장 기능이 있습니다.

SHELL=/bin/tcsh
* * * * * if (-Z /cache/myfile.csv > 5*1024*1024*1024) echo 'file is > 5GiB'

또는 zsh여기에서 glob 한정자와 익명 함수를 사용하여 를 사용하세요. 하지만 zsh에는 stat GNU 및 BSD 이전의 내장 함수 도 있습니다 stat.

SHELL=/bin/zsh
* * * * * (){ if (($#)) echo 'file is > 5GiB'; } /cache/myfile.csv(NLG+5)

( find -size +5G여기서는 기가바이트(1GB = 1,000,000,000바이트)가 아니라 기가바이트(1GiB = 1,073,741,824바이트)에 대해 이야기하고 있습니다.)

심볼릭 링크의 경우 tcsh최종적으로 확인되는 파일의 크기를 얻는 반면, s와 같은 한정자는 심볼릭 링크 자체의 크기를 확인합니다 zsh. LG+5심볼릭 링크의 해결된 크기를 확인하도록 변경되었습니다. 내장 함수는 기본적으로 심볼릭 링크가 해결된 후 심볼릭 링크를 변경하기 위한 정보를 제공합니다. GNU와 BSD에서는 상황이 반대입니다. 심볼릭 링크를 따르라고 지시하는 것과 동일합니다.find-size-LG+5zshstat-Lstatfind-L

파일 크기를 확인하는 더 많은 방법은 다음을 참조하세요.Bash 스크립트에서 파일 크기를 얻는 방법은 무엇입니까?

관련 정보