저는 C:\
두 가지 다른 유형의 파일을 모두 /root
.
내 나무는 다음과 같습니다
- Batch
- Place of the script
- Conf
- Appli1
- File1.xml
- File2.xml
- ...
- Appli2
- File1.xml
- File2.xml
- ...
- ...
- Info
- File1.conf
- File2.conf
- ...
내 스크립트는 다음과 같습니다 /Batch
.
#/bin/bash
find ../ -name "*.xml" -o name "*.conf" -print | xargs sed -i 's C:\ /root/ g'
그러나 오류가 있습니다 sed part
.character 14: command 's' unfinished
왜 이런 일이 발생합니까?
답변1
당신은 어디에 사용합니까:
sed -i 's C:\ /root/ g'
당신은 사용하고 있습니다s
주문하다명령의 여러 부분을 공백 문자로 구분하는 것은 드물지만 완전히 유효합니다. 그러나 구분 기호 앞에 백슬래시가 있으면 구분 기호로 처리되지 않고 매개 변수 자체의 일부로 처리됩니다.
여기서 문제는 백슬래시가 C:\
중간 공백을 벗어나므로 s
대체 끝을 찾을 수 없으며(현재로서는 g
) 보시다시피 명령이 완료되지 않는다고 불평한다는 것입니다.
최소한 다른 백슬래시를 사용하여 백슬래시 자체를 이스케이프 처리해야 합니다.
sed -i 's C:\\ /root/ g'
공백을 다른 문자로 바꾸는 것이 더 명확할 수도 있지만 이 방법은 작동합니다.
귀하의 용도에 관해서는xargs
및 하위 디렉토리 - xargs
여기서는 필요하지 않습니다.find
하위 디렉터리의 파일 처리를 포함하여 이 작업을 직접 수행할 수 있습니다. 사용:
find ../ \( -name "*.xml" -o -name "*.conf" \) -exec sed -i -e 's|C:\\|/root/|g' '{}' +
find
명령 sed
자체와 찾은 모든 파일 이름을 실행하십시오 . 대신 파일 이름을 삽입하면 명령 실행 횟수가 최소화 {}
됩니다 .+
find
-execdir
-exec
아마도 설명된 일부 보안상의 이유보다 더 나을 것입니다.find
매뉴얼 페이지; 비표준 확장이지만 GNU 도구를 사용하는 것 같으니 필요할 경우 있어야 합니다.
답변2
이것은 백슬래시입니다. 백슬래시는 다음 문자를 파괴하고 특별한 의미를 잃습니다. sed 명령은 사용자가 입력한 내용을 읽습니다(여기서는 sed 표현식만 사용하고 지루한 쉘 명령줄 전체를 수행하지는 않습니다).
s
<SPACE>
C
:
Literal <SPACE>
/root/
<SPACE>
찾기 위한 표현식으로 사용하려는 토큰과 그 교체를 sed에게 지시했습니다. 하지만 sed는 다음과 같은 것을 보고 싶어합니다:
s
<SPACE>
C
:
Literal \
<SPACE>
/root/
<SPACE>
백슬래시를 리터럴 백슬래시로 바꾸려면 백슬래시 앞에 백슬래시를 추가하세요.
sed -e 's C:\\ /root '
개인적으로는 공백을 사용하지 않는 것이 좋습니다. 나는 |
같은 것을 사용하거나 ;
. 그러나 백슬래시에는 여전히 문제가 있습니다. 정말 흥미로운 점은 백슬래시를 구분 기호로 사용하기 위해 입력해야 하는 내용을 알아내는 것입니다. :)