가변 길이 파일 이름을 식별하는 데 적합한 정규식은 무엇입니까?

가변 길이 파일 이름을 식별하는 데 적합한 정규식은 무엇입니까?

원격 서버에서 파일을 분류하고 검색하는 bash 스크립트가 있습니다. 파일 이름을 기반으로 하는 분류 단계에 문제가 있습니다.

파일 이름의 시작 부분으로 정의된 다양한 파일 계열을 올바르게 식별할 수 있습니다.

ala-olo_ulu-1602915797.txt
ala-olo_ulu-1602915799.txt
ili-olo-1602915897.txt
ili-olo-1602915997.txt
ili-olo-pip-1602925797.txt
ili-olo-pip-1602935797.txt

이 예에는 3개의 가족이 있습니다. ala-olo_ulu ili-olo ili-olo-pip (순수한 예 :))

각 가족은 루프의 한 번의 반복으로 처리됩니다. 이러한 반복에서는 변수에서 사용할 수 있는 가족 이름이 있습니다 BASE_NAME(예: ili-olo).

내 문제는 파일을 로컬로 rsync'ing하기 전에 다음 ssh 명령을 사용하여 관리하는 단계입니다.

      ssh root@"${RMT_IP}" '
          for FILE in "'${BASE_NAME}'*'${FILE_EXTENSION}'"; do
            tar -rf "'${BASE_NAME}'.tar" ${FILE} --remove-files
          done' < /dev/null

안타깝게도 이 스크립트를 사용하면 ili-olo이전에 관리된 경우 ili-olo-pip아카이브에 두 개의 시리즈(둘 다 동일한 시작을 공유함)가 포함됩니다. 관리 되면 ili-olo-pip더 이상 파일이 아니며 tar 명령은 오류와 함께 종료됩니다. (이것이 내가 문제를 발견한 방법이다).

나는 파일 이름의 변수 부분이 숫자 부분임을 지정하려면 정규 표현식을 사용해야 한다고 생각했습니다. for동일한 문자열로 시작하는 시리즈가 동일한 tar에 들어 가지 않도록 루프 정의를 어떻게 변경할 수 있습니까 ?

for FILE in "'${BASE_NAME}'*'${FILE_EXTENSION}'"; do

?

예를 들어 숫자 부분은 항상 동일한 자릿수를 갖습니다(초 단위의 타임스탬프입니다).1602915797

귀하의 도움에 감사드립니다. 좋은 하루 보내세요, 베스트, 피에르

답변1

로컬 및 원격 셸로 모두 사용할 수 있으면 zsh훨씬 더 쉽습니다 .

ssh root@$RMT_IP zsh << EOF
  set -o extendedglob # for (#c10)

  for file in ${(qq)BASE_NAME}-[0-9](#c10).${(qq)FILE_EXTENSION}(N); do
    tar -rf ${(qq)BASE_NAME}.tar \$file --remove-files
  done
EOF

[0-9](#c10)10진수 시퀀스와 일치합니다. [0-9]##하나 이상의 숫자 또는 (반드시 그런 것은 아님) 동일한 십진수 시퀀스로 구성된 범위의 숫자를 참조하세요 .[0-9](#c1,)<100000-9999999999>extendedglob

sshd서버에서 사용자의 로그인 셸을 실행하여 인수로 전달된 코드를 해석합니다. 우리는 그것이 무엇인지 모르기 때문에(보통 root) 쉘을 시작 하고 표준 입력으로 코드를 전달하기 위해 sh이 코드를 작성합니다 .zshzshzsh

이와 같은 문서를 사용하면 원격 셸에서 해석되는 셸 코드를 더 쉽게 구성할 수 있습니다. 인용되지 않았기 때문에 EOF로컬 쉘은 로컬로 확장을 수행합니다.

로컬에서 수행해야 하는 확장과 원격 셸에서 수행해야 하는 확장을 추적하는 것이 중요합니다.

위의 내용은 ${(qq)BASE_NAME}로컬 셸에 의해 확장됩니다. (qq)매개변수 확장 플래그를 사용하여 결과를 작은따옴표로 묶어 원격 셸이 이를 리터럴 문자열로 처리하도록 합니다.

$file원격 셸에 의해 확장되어야 하므로 리터럴을 원격 셸에 전달하기 \위해 접두사를 붙입니다.$file

zsh원격 컴퓨터에서 사용할 수 없지만 사용할 수 있는 경우 bash다음을 수행할 수 있습니다(여전히 zsh로컬에서 작업 중).

ssh root@$RMT_IP bash --norc << EOF
  shopt -s extglob nullglob # for +(...)
  export LC_ALL=C

  for file in ${(qq)BASE_NAME}-+([0-9]).${(qq)FILE_EXTENSION}; do
    tar -rf ${(qq)BASE_NAME}.tar "\$file" --remove-files
  done
EOF

bashzshglob 연산자 와 동등한 것은 없지만 x(#c10)사용되면 하나 이상의 일치를 포함하여 ksh의 하위 집합(불행히도 여기에는 없음) extglob을 지원합니다 . 이는 단지 10이 아닌 하나 이상의 숫자와 일치합니다.{10}(x)+(x)x+([0-9])

10자리 숫자를 일치시키려면 이 작업을 수행할 수 있습니다 [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].

관련 정보