>>>
파일에서 ""를 ""로 바꾸려고 합니다.
cat table_files.md | egrep ">>>$"
\>>>
\>>>
\>>>
\>>>
\>>>
\>>>
\>>>
\>>>
\>>>
sed로 교체하세요
cat table_files.md | sed "s\>>>$\\g" > table_files.md
불행하게도 모든 데이터가 사라졌고 빈 파일이 반환되었습니다. -i
내부 옵션을 사용하여 이 작업을 수행해야 하는지 확인했습니다 .
어떻게 이런 일이 일어날 수 있나요? 데이터를 복구할 수 있나요?
답변1
파일을 덮어쓰거나 잘리는 이유는 해당 파일이 귀하의 파일이기 때문입니다.껍데기리디렉션을 해석하고 명령이 실행되기 전에 이 해석을 수행합니다. 쉘 작업의 중요한 부분은 다양한 것들 사이의 표준 입력과 표준 출력을 연결하는 파이프를 처리하는 것입니다. 다음과 같은 명령줄을 실행했습니다.
$ command1 < somefile | command2 > somefile
실행하기 전에도 command2
쉘은 명령의 출력을 파일로 지정하는 리디렉션을 해석하여 파일을 자릅니다. 파일이 잘린 후에 command1
는 읽을 입력이 없으므로 command2
파일로 리디렉션할 데이터를 내보내지 않고 파일이 종료되는 파이프를 닫고 종료됩니다.
두 가지 질문이 있는 것 같습니다.
1. 덮어쓴 파일을 복구할 수 있나요?
아마도 그렇지 않을 것입니다. 가능하다면 백업을 복원하여 이 작업을 수행할 수 있습니다. 파일을 다른 데이터로 덮어쓰면 일반적으로 파일의 이전 버전이 제거됩니다.
2. 파일의 데이터를 바꾸는 가장 좋은 방법은 무엇입니까?
짐작할 수 있듯이 이를 수행하는 가장 좋은 방법은 다음과 같습니다.sed(in-place) 옵션이 사용됩니다 -i
. 기억해, 이건 아니야진짜제자리에서 편집하세요. 이 -i
옵션을 사용하면 sed가 모든 입력을 읽고 수정하여 임시 저장소에 저장하고 완료되면 모든 것을 임시 저장소에서 원본 파일로 다시 이동합니다.
BSD sed(macOS 포함):
sed -i '' 's:>>>$::' $filename
그러나 GNU sed(대부분의 Linux 배포판)에서는 지정되지 않은 optarg to가 -i
null로 간주됩니다.
sed -i -e 's:>>>$::' $filename
>>>
이렇게 하면 줄의 끝이 제거됩니다 . 한 줄 내에서 문자열을 제거하려면 줄 끝에 고정되지 않도록 정규식을 수정하고( ) 줄당 여러 문자열에 적용하는 $
플래그를 추가합니다 .g
sed -i '' 's:>>>::g' $filename
운영 체제에 따라 sed가 다르게 실행됩니다. 공유하고 싶은 도구를 작성할 때 모든 사람이 동일한 운영 체제를 실행하는 것은 아니라는 점을 기억하는 것이 중요합니다. 휴대성이 중요합니다. 이식성을 높이려면 지원하려는 모든 플랫폼에서 사용할 수 있는 기능의 "최저 공통 분모"를 사용하도록 스크립트를 단순화해야 할 수도 있습니다. 그러므로:
tmpfile=$(mktemp /tmp/$$XXXX)
sed -e 's:>>>$::' $filename > $tmpfile &&
mv $tmpfile "$filename"