찾기 명령: 작은따옴표 및 큰따옴표

찾기 명령: 작은따옴표 및 큰따옴표

Find를 사용하여 파일 이름을 바꾸고 있습니다.

이것은 작동합니다:find . -iname a* -exec bash -c 'x={};mv {} ${x/a/b}' \;

하지만 그렇지 않습니다: find . -iname a* -exec bash -c "x={};mv {} ${x/a/b}" \;

왜?

Bash에서 실행됩니다.

감사해요

답변1

먼저 다음을 참조하세요.셸에서 "...", '...', $'...' 및 $"..." 따옴표의 차이점은 무엇입니까?

이것은 작동합니다:find . -iname a* -exec bash -c 'x={};mv {} ${x/a/b}' \;

현재 디렉토리에 로 시작하는 파일 이름이 없고 a트리의 파일 이름에 공백이나 쉘 특정 문자가 없으면 예, 아마도 작동할 것입니다.

하지만 그렇지 않습니다:find . -iname a* -exec bash -c "x={};mv {} ${x/a/b}" \;

"x={};mv {} ${x/a/b}"부분은 큰따옴표로 묶여 있으므로 ${...}명령을 실행하기 전에 쉘이 여기에서 확장됩니다. 결과 문자열 은 셸에서 설정될 가능성이 없으므로 결과 find문자열만 볼 수 있습니다 .x={};mv {}$x

첫 번째 항목에서는 작은따옴표가 확장을 방지하므로 find참조하여 x={};mv {} ${x/a/b}파일 이름을 바꾸고 {}실행하도록 요청한 셸에 결과를 전달합니다. 효과가 있을 수도 있습니다.


그러나 여기에는 몇 가지 문제가 있습니다. 첫 번째 것은 인용되지 않았습니다 -iname a*. 이것은 실행하기 전에 쉘에서 glob을 확장하므로 find디렉토리에 eg가 포함되어 있으면 실행하는 abcd.txt것과 asdf.txt동일합니다 find . -iname abcd.txt asdf.txt. 첫 번째 파일 이름은 이고 -iname, 두 번째 파일 이름은 오류입니다.

그런 다음, 예를 들어 트리 어딘가에 있는 파일 이름을 {}생각해 보십시오 . 셸에서 변경 하고 실행합니다. 그러나 이는 원하는 구문이 아니며 , run 및 명령으로 할당 됩니다 . 이와 같이 코드와 데이터를 혼합하는 것은 작업하기가 거의 불가능합니다. 특히 다음을 포함할 수 있는 파일 이름의 경우 더욱 그렇습니다.foo bar.txtfindx={};mv {} ${x/a/b}x=foo bar.txt;mv foo bar.txt ${x/a/b}fooxbar.txt모든 문자. 이는 또한 foo; echo doing bad things.


올바른 방법은 파일 이름을 위치 인수로 내부 쉘에 전달하고 스크립트에서 확장자를 참조하는 것입니다.

그래서,

find . -iname "a*" -exec bash -c 'mv "$1" "${1/a/b}"' sh {} \;

바라보다:

관련 정보