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 ....
얻은 결과를 알려주십시오.)