내가 실행하면 :
cat messages.txt | sed -e 's/a/a/g' > messages.txt
큰 파일(2500개 이상의 라인)에서 cygwin의 명령 이후 생성된 파일에는 약 900라인만 있는 반면 gentoo에서는 라인이 없다는 것을 발견했습니다. 하지만 내가 달리면
cat messages.txt | sed -e 's/a/a/g' > other_messages.txt
모든 라인을 그대로 유지합니다.
내 질문은 왜 게다가
cat messages.txt | sed -e 's/a/a/g' > other_messages.txt
rm messages.txt
mv other_messages.txt messages.txt
답변1
베르슈미트의 답변sed를 사용할 때 가장 좋습니다. 그러나 보다 일반적인 의미에서는 다음과 같은 안티 패턴이 있습니다.
cat infile | filter > infile
많은 문제가 발생할 수 있습니다. 예를 들어 다음과 같은 파일이 있다고 가정해 보겠습니다 infile
.
Hello
World
그리고 다음 명령을 실행하세요:
cat infile | tr "[:upper:]" "[:lower:]"
알겠어요
hello
world
하지만 실행하면 cat infile | tr "[:upper:]" "[:lower:]" > infile
빈 파일이 나타납니다. 왜?
글쎄요, 출력 리디렉션 연산자를 사용하면 >
"내 표준 출력을 이 파일에 넣고 파일이 존재하면 덮어씁니다."라고 말하는 것입니다. 이제 필터링 때문에 이것이 작동해야 한다고 생각할 수도 있습니다. 컴파일러는 원본의 모든 줄을 반환합니다. 파일. 그러나 종종 발생하는 일은 쉘이 행을 읽기 전에 파일을 손상시키는 것입니다. 그런 다음 필터 명령은 빈 파일에서 행을 읽고 아무것도 찾지 않으므로 없음을 반환합니다. 어떤 곳에서는 파일이 손상되기 전에 일부 줄을 읽을 만큼 "운이 좋을" 수도 있지만, 이 패턴을 완전히 피하는 것이 가장 좋습니다.
이 특정 문제를 해결하려면 몇 가지 옵션이 있습니다. 하나는 간단히 다음을 수행하는 것입니다.
cat infile | filter > tmpfile; mv tmpfile infile
임시 파일이 다른 파일을 손상시키지 않거나 다른 불쾌한 일을 수행하지 않는지 확인해야 하는 경우 를 확인해야 합니다 ( 및 mktemp
참조 ) .man mktemp
info coreutils mktemp
또 다른 옵션은 다음 sponge
에서 사용하는 것입니다.더 많은 유틸리티.
게다가 이러한 예 중 상당수는고양이에게 쓸모없는 용도.
답변2
그냥 쓰는 게 어때?
sed -i -e 's/a/a/g' messages.txt
-i는 "제자리에"를 의미합니다.
답변3
파일을 제자리에서 편집하는 또 다른 (이식 가능한) 방법은 를 사용하는 것입니다 ed
.
# cf. http://wiki.bash-hackers.org/howto/edit-ed
cat <<-'EOF' | ed -s messages.txt
H
,g/a/s//b/g
wq
EOF
# ... or read the file contents into a variable, modify it and write it back to file
file_contents="$(cat messages.txt)"
printf '%s' "$file_contents" | sed -e 's/a/b/g' > messages.txt
# ... and, if you want to play around with a file descriptor hack, ...
# (As long as there's a fd associated with a file, the file can be accessed via the fd.)
exec 3<messages.txt # open file on fd 3 for reading
rm -f messages.txt
sed -e 's/a/b/g' <&3 > messages.txt
답변4
Ex 모드에서 Vim을 사용할 수 있습니다:
ex -sc '%s/OLD/NEW/g|x' messages.txt
%
모든 행 선택s
바꾸다g
전역 교체x
저장하고 닫습니다