작은따옴표를 포함하도록 파일 이름을 어떻게 바꾸나요?

작은따옴표를 포함하도록 파일 이름을 어떻게 바꾸나요?

내 Ubuntu 시스템에는 /var/www이름이 잘못된 여러 파일이 웹 루트 폴더에 분산되어 있습니다.

GermanyXXXs-enchanting....

다음 출력을 얻으려면 XXX를 아포스트로피 '로 바꾸고 싶습니다.

Germany's-enchanting....

다음 명령은 일반 문자에서는 작동하지만 이스케이프하더라도 따옴표에서는 작동하지 않습니다.

find /var/www/html -name '*XXX*' -exec bash -c ' mv $0 ${0/XXX/\'}' {} \;

답변1

Bourne과 같은 셸에서는 작은따옴표로 묶인 문자열 내에 작은따옴표를 사용할 수 없으며 , , ...를 사용하여 다른 방법으로 인용 \'해야 "'"합니다 $'\''.

또한 에서 bash매개변수 확장은 적어도 목록 컨텍스트(예: 명령의 매개변수)에서 큰따옴표로 묶어야 한다는 점을 기억하십시오.

재귀적으로 이름을 바꾸는 경우 파일 이름도 바뀌었는지 확인해야 합니다.깊이 우선파일의 기본 이름 부분(디렉토리 구성 요소가 아님)만 이름을 바꾸십시오.

find /var/www/html -depth -name '*XXX*' -execdir bash -c '
  ret=0
  for file do
    mv -- "$file" "${file/XXX/\'\''}" || ret=$?
  done
  exit "$ret"' bash {} +

이 참조는 외부 참조 '입니다 .\''...'

$file"$file"분할+글로브를 피하기 위해 목록 컨텍스트에서 참조됩니다 . $?스칼라(목록/배열이 아님) 변수에 대한 할당이므로 참조가 필요하지 않지만 쓰기에는 ret="$?"문제가 없습니다.

-execdir( 여기서 사용된 $file기본 이름 ( ./일부 find구현에 의해 접두어가 붙을 수 있음))은 비표준 확장이지만 현재 비교적 널리 지원된다는 점에 유의하세요 .

-execdir cmd {} +( +대신 )을 사용할 때 ;일부 find구현에서는 가능하면 여러 파일을 인수로 호출하려고 시도 cmd하지만 더 중요한 것은 cmd종료 상태(있는 경우)에 오류가 보고되도록 허용한다는 것입니다.find

또는 전용 일괄 이름 바꾸기 도구를 사용할 수 있습니다. 예를 들어 bash 대신 zsh를 사용하는 경우 zmv자동 로드 기능을 사용할 수 있습니다.

autoload -Uz zmv
zmv '(**/)(*XXX*)' '$1${2/XXX/'\''}'

위의 모든 요소를 ​​고려하고 데이터 손실을 방지하기 위해 사전에 몇 가지 온전성 검사를 실행하는 이유는 무엇입니까?

숨겨진 파일이 남습니다. 이름을 바꾸려면 다음과 같이 변경하세요.

zmv '(**/)(*XXX*)(#qD)' '$1${2/XXX/'\''}'

시험 실행을 위한 -n옵션을 추가할 수 있습니다 .zmv

답변2

작은따옴표 쌍 내의 작은따옴표는 작은따옴표를 닫고 를 입력한 \'다음 작은따옴표 쌍을 다시 시작하여 이스케이프할 수 있습니다.

echo 'It isn't hard'     # broken
echo 'It isn'\''t hard'  # fixed

끊어진 문자열을 세 개의 단위 'It isn'\'합계로 변환합니다 't hard'. 다르게 생각하면 작은따옴표 '안의 모든 문자 '...'는 로 대체되어야 합니다 '\''.

관련 정보