Bash 복합 하위 문자열 확장

Bash 복합 하위 문자열 확장

awk여러 구분 기호를 구문 분석하는 데 사용할 수 있다는 것을 알고 있지만 이렇게 하면 하위 프로세스가 생성됩니다. 복합/중첩 bash 매개변수 확장이 가능한지 궁금합니다.

내 PDF 파일은 "Px_MM-DD-YY_SSSSSSSSSS.pdf"라는 디렉터리에 있습니다.

  • "Px"는 "페이지 x"를 의미하며 x에는 앞에 0이 없습니다.
  • "MM"은 두 자리 월에 해당하며 해당하는 경우 앞에 0이 붙습니다.
  • "DD"는 두 자리 날짜에 해당하며 해당하는 경우 앞에 0이 붙습니다.
  • "YY"는 두 자리 연도에 해당하며 해당하는 경우 앞에 0이 붙습니다.
  • "SSSSSSSSSS"는 PDF가 생성된 10자리 신기원 시간에 해당하므로 PDF 페이지 개정판을 보존할 수 있습니다.

for 루프가 있습니다(모든 PDF에서 작업할 준비가 되면 "-mtime"을 제거합니다).

for file in $(find -type f -iname '*_??????????.pdf' -mtime -1)
do
    echo $file
done

나는 단지 시대의 시간을 반영하고 싶습니다.

이것을 루프에 사용할 수 있습니다

for file in $(find -type f -iname '*_??????????.pdf' -mtime -1)
do
    echo ${file##*_}
done

"./P14_07-21-18_4X_1532144458.pdf"라는 파일의 경우 "1532144458.pdf"가 화면에 표시됩니다.

이것을 루프에 사용할 수 있습니다

for file in $(find -type f -iname '*_??????????.pdf' -mtime -1)
do
    echo ${file%.*}
done

"./P14_07-21-18_4X_1532144458.pdf"라는 파일의 경우 "./P14_07-21-18_4X_1532144458"이 화면에 표시됩니다.

echo ...줄을 아래 형식 중 하나로 바꾸면

echo ${${file##*_}:0:10}
echo ${(${file##*_}):0:10}
echo ${${file##*_}%.*}
echo ${{file%.*}##_}
echo ${${file%.*}##_}

알겠어요 -bash: ... : bad substitution. 내 구문이 정확합니까, 아니면 중첩/복합 bash 확장이 불가능합니까?

답변1

중첩된 대체를 수행할 수 없습니다.변수는 가장 왼쪽 부분에 있습니다.. 그래서 당신은 그것을 할 수 있지만 ${foo#$bar}당신이 보여주는 것은 아닙니다.

대체 결과를 추가 대체에 사용하려면 대체 결과를 변수에 넣으십시오.

답변2

먼저 초기 결과를 변수에 저장하고 두 번째 대체를 적용하지 않고는 다른 매개변수 대체 결과에 대해 매개변수 대체가 작동하도록 할 수 있는 방법이 없습니다.

출력을 반복할 수도 있습니다 find.권장되지 않음.

루프에 대한 결과를 제공하는 올바른 방법 find은 서브셸을 호출하고 그 안에서 루프를 실행하는 것입니다.

find . -type f -iname '*_??????????.pdf' -mtime -1 -exec sh -c '
    for pathname do
        timestamp=${pathname##*_}   # remove up to last _
        timestamp=${timestamp%.pdf} # remove .pdf
        printf "pathname=%s\ttimestamp=%s\n" "$pathname" "$timestamp"
    done' sh {} +

이렇게 하면 실제 경로 이름이 무엇인지 걱정할 필요가 없습니다. Unix의 파일 이름(즉, 파일 이름, 디렉터리 및 기타 파일 형식 이름)에는 공백 및 개행과 같이 및 /를 제외한 모든 문자가 포함될 수 있습니다. \0에서 명령 대체를 사용하면 find쉘이 먼저 단어 분리(기본적으로 공백, 탭 및 줄 바꿈)를 수행한 다음 에서 반환된 경로 이름에서 발견된 패턴을 기반으로 파일 이름 생성을 수행하도록 할 수 있습니다 find. 따라서 원래 루프는 의도한 것과 완전히 다른 단어를 반복하게 될 수도 있습니다.

관련된:

답변3

내가 올바르게 이해했다면 Awk 사용의 문제점은 각 PDF 파일에 대해 Awk 프로세스를 호출한다는 것입니다(많은 파일이 있다고 가정합니다).

다음과 같이 뭔가를 실행할 수 있습니다

find . ...... -print0 | perl -0nE '/.*_(\d{10}).pdf/ and say "$1.pdf"'

또는 구조를 유지하는 경우:

for file in $(find .....| perl ....)
do 
  ...
done

(물론 Perl 명령을 Awk, sed, Python에 해당하는 명령으로 바꾸십시오)

(이 방법을 시도해 볼 기회가 있으면 time ....얻은 결과를 알려주십시오.)

관련 정보