디렉터리에 여러 파일이 있는지 확인하고 동일한 파일을 압축하는 방법

디렉터리에 여러 파일이 있는지 확인하고 동일한 파일을 압축하는 방법

동일한 문자열/패턴으로 끝나는 파일이 있는지 확인하는 데 문제가 있습니다. 파일 이름은 다음과 같을 수 있습니다.

abs_123.unl
xyz_123.unl

현재 내 코드는 다음과 같습니다. 단일 파일에서는 제대로 작동하지만 동일한 패턴의 파일이 여러 개 있으면 if 조건이 실패합니다.

if [ -s $AZWORK/*$PRCSID.unl ]
then
  tar -cvzf $WORK/INET_$PRCSID.unl.gz $WORK/*$PRCSID.unl
fi

여기서 $PCSID는 파일의 마지막 세 자리를 나타냅니다.

이 쉘 스크립트를 여러 파일에서 작동하게 하려면 어떻게 해야 합니까?

답변1

파일의 "찾기" 및 "크기 조정"을 다음 사용자에게 위임합니다 find.

find "$WORK" -maxdepth 1 -name "*$PRCSID.unl" -type f  ! -size 0 -print0 | \
   xargs -0 --no-run-if-empty tar -cvzf "$WORK/INET_$PRCSID.unl.gz"

"*_123.unl"이렇게 하면 해당 패턴이 있을 수 있는 하위 디렉터리를 필터링할 수도 있습니다 .

옵션 find:

  • -maxdepth 1하위 디렉터리로의 재귀 방지
  • -name "*$PRCSID.unl"*쉘 확장을 방지하기 위해 파일 이름을 인용하여 파일 이름과 일치시킵니다 .
  • -type f파일만
  • ! -size 0크기가 중요합니다!
  • -print0NUL로 구분된 이름을 인쇄합니다. 여기서 꼭 필요한 것은 아니지만 파일 이름에 개행 문자가 포함되어 있어도 문제가 되지 않습니다.

옵션/매개변수 xargs:

  • -0stdin이 NUL로 구분되어 있다고 가정합니다(개행으로 구분되지 않음).
  • --no-run-if-empty표준 입력에 데이터가 없으면 실행되지 않습니다(즉, find에는 출력이 있습니다).
  • 나머지 줄은 실행할 명령으로 stdin의 데이터를 인수로 추가합니다.

답변2

간단히 이렇게 할 수 있습니다:

tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID.unl"

답변3

패턴과 일치하는 파일이 있는지 확인하려면 다음과 같이 할 수 있습니다.

만약에 ["$(shopt -s nullglob; printf "%s" "$WORK"/*"$PRCSID".unl)" != ""]
그 다음에
    tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl
필리핀 제도

.unl( 한 위치에서 파일을 찾은 다음 다른 위치에서 보관할 계획은 없다고 가정합니다 .)

shopt -s nullglob파일 이름 패턴이 일치하는 항목이 없으면 파일 이름 패턴이 아무 것도 "확장"되지 않으므로 작업 디렉터리에 이름이 it로 끝나는 파일이 없으면 123.unl문자열 인수가 "$WORK"/*"$PRCSID".unl사라지고 printf인쇄할 항목이 남지 않습니다.

노트:

  • shopt -s nullglob예를 들어 external 선언을 사용할 수 있습니다 if.
    shopt -s nullglob                        # 아마도 스크립트의 다른 곳에 있을 수도 있습니다.
       ⋮
    if [ "$(printf "%s" "$WORK"/*"$PRCSID".unl)" != "" ]
    그 다음에
        tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl
    필리핀 제도
    스크립트를 실행하여 이 동작(일치하지 않는 패턴의 빈 확장)을 활성화하려는 경우.
  • 특별한 이유가 없는 한 항상 쉘 변수(예: "$WORK"and )를 인용해야 합니다."$PRCSID"틀림없이당신은 당신이 무엇을하고 있는지 알고 있습니다. 변수를 참조하기만 하면 단편적으로 수행할 수 있습니다.
    "$WORK"/*"$PRCSID".unl 및 "$WORK"/INET_"$PRCSID".unl.gz
    또는 변수가 포함된 전체 단어를 인용할 수 있습니다. 예를 들면 다음과 같습니다.
    "$WORK/"*"$PRCSID.unl" 및 "$WORK/INET_$PCSID.unl.gz"
    "$WORK/*$PRCSID.unl"그러나 이렇게 하면 *파일 이름 확장 패턴(예: 와일드카드 또는 glob)으로 작동하지 않도록 따옴표로 묶어서 이를 수행할 수 없습니다 .
  • 파일 이름 패턴은 제어할 수 있는 디렉터리 이름으로 시작하므로 특히 전체 경로( 로 시작 /)인 경우 또는 최소한 보장할 수 있습니다.아니요첫 번째-echo) — 그렇다면 IE를 사용해 도 안전할 것입니다 printf "%s".
    만약 ["$(shopt -s nullglob;에코"$WORK"/*"$PRCSID".unl)" != "" ]
    그 다음에
        tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl
    필리핀 제도
    물론 여기 성명서에서 shopt -s nullglob 이 내용을 삭제할 수도 있습니다.if

또 다른 방법

만약 너라면필요if예를 들어 상태/로그/오류 메시지를 작성하려면 - then- else(또는 적어도 if- )를 가지려면 then위의 방법을 사용해야 할 것입니다. 그러나 tar파일이 있는 경우에만 명령을 실행하는 것이 유일한 관심사라면 생략 if하고 then수행 할 수 있습니다.

(shopt -s 결함 글로벌;tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl)

shopt -s failglob즉, 어떤 것과도 일치하지 않는 파일 이름 패턴이 포함된 인수를 사용하여 명령을 실행하려고 하면 명령이 실행되지 않았습니다.. 위의 내용은 귀하의 질문에 있는 코드가 달성하려는 작업을 정확하게 수행합니다. tar작업 디렉터리에 이름이 로 끝나는 파일이 있으면 명령을 실행 123.unl 하고 그렇지 않으면 실행하지 않습니다.

shopt -s failglob마찬가지로 명령 과 명령을 분리할 수 있습니다 tar.

shopt -s 결함 글로벌                        # 아마도 스크립트의 다른 곳에 있을 수도 있습니다.
   ⋮
tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl
스크립트를 실행하여 해당 동작을 달성하려는 경우(일치하지 않는 패턴으로 명령을 실행하지 않음)

답변4

find명령은 필요한 파일을 찾은 다음 다음과 같은 결과에 대해 명령을 실행할 수 있습니다.

find $WORK -name *.unl -exec tar -zcvf $WORK/INET_$PRCSID.unl.gz {} \;

관련 정보