![For 루프 및 위치 지정 명령 정규식이 일치하지 않습니다.](https://linux55.com/image/14316/For%20%EB%A3%A8%ED%94%84%20%EB%B0%8F%20%EC%9C%84%EC%B9%98%20%EC%A7%80%EC%A0%95%20%EB%AA%85%EB%A0%B9%20%EC%A0%95%EA%B7%9C%EC%8B%9D%EC%9D%B4%20%EC%9D%BC%EC%B9%98%ED%95%98%EC%A7%80%20%EC%95%8A%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
구성을 변경할 때 접미사가 .original인 원본 파일의 복사본을 만듭니다. 이제 모든 *.original 파일을 찾고 .original 접미사가 있거나 없는 두 버전을 모두 사용하는 간단한 스크립트를 작성 중입니다.
경로 중간에 있는 문자열과 locate
파일이 일치하지 않는 것을 피하기 위해 정규식과 함께 명령을 사용했습니다 .original
내 명령이 locate --regex ^.*\\.original$
완벽하게 실행 되고 있습니다 in terminal
. .original 접미사로 끝나는 모든 파일을 찾습니다.file.original
하지만in bash script
에서 동일한 명령을 사용하면 다음과 같은 변형이 for loop
반환됩니다 .file.original
file-original
file_original
.original 파일만 얻으려면 정규식이나 for 루프를 어떻게 수정해야 합니까?
내 껍질은 다음과 같습니다
$ echo $BASH
/usr/bin/bash
내 bash 스크립트는 다음과 같습니다
#!/usr/bin/bash
echo "Plain locate command:"
locate --regex ^.*\\.original$ | grep test
echo "For loop:"
for file in `locate --regex ^.*\\.original$ | grep test`; do
echo $file
done
테스트에 사용할 수 있습니다.
mkdir /tmp/test
touch /tmp/test/file.original
touch /tmp/test/file-original
touch /tmp/test/file_original
updatedb
locate --regex ^.*\\.original$
내 터미널에서 다음을 찾습니다.
/tmp/test/file.original
하지만 내 스크립트에서는 다음을 찾습니다.
Plain locate command:
/tmp/test/file.original
For loop:
/tmp/test/file-original
/tmp/test/file.original
/tmp/test/file_original
답변1
백틱에는 더 많은 이스케이프가 필요합니다. 이것이 당신이 그것을 선호해야 하는 이유 중 하나입니다 $()
(이 답변의 "백슬래시 재미" 참조:$(stuff)
이들그리고 그리고 의 차이점은 무엇인가요 `stuff`
?).
백틱 내에서 이스케이프 처리가 충분하지 않기 때문에 문자열이 결국 정규 표현식으로 해석될 때 이스케이프하려는 지점이 이스케이프되지 않습니다.
관련 줄을 다음과 같이 변경합니다.
for file in $(locate --regex '^.*\.original$' | grep test); do
노트:
백슬래시를 편리하게 처리하기 위해 작은따옴표를 사용합니다.그리고별표. 원본 코드에서 따옴표가 없고 이스케이프 처리되지 않은 별표는 트리거될 수 있습니다.파일 이름 확장자.
^.*
정규식에는 아무것도 변경되지 않았습니다. 작은따옴표로\.original$
충분합니다.^.*
파일명 확장 가능성을 지적하기 위해 그대로 유지하기로 결정했습니다 .에 익숙해참조 변수(예를 들어
echo "$file"
). 연결된 답변 도 인용을 제안하지만 이는$()
루프for
에서는 잘못된 것입니다 . 인용하지 않는 것도$()
실수입니다. 둘 다 틀렸기 때문에…일반적으로 말하면
for
이런 루프를 만드는 것은 일반적으로 실수입니다.. 이것은Bash의 첫 번째 함정. 더 나은 출력 으로locate
작업을 수행 하려면xargs
null로 끝나는 문자열로 처리하는 것이 가장 좋습니다.locate -0 … | grep -z … | xargs -r0 …
이러한 옵션은 이식 가능하지 않습니다.