나는 이것이 다른 질문과 일종의 중복이라는 것을 알고 있습니다 (이 정렬 명령이 빈 파일을 제공하는 이유는 무엇입니까?) 하지만 주어진 답변을 바탕으로 질문을 확장하고 싶습니다.
주문하다
shuf example.txt > example.txt
쉘이 파일을 섞기 전에 잘라내어 섞을 빈 파일만 남기기 때문에 빈 파일이 반환됩니다. 하지만,
cat example.txt | shuf > example.txt
예상대로 스크램블된 파일이 생성됩니다.
파이프 방법은 작동하지만 단순 리디렉션은 작동하지 않는 이유는 무엇입니까? 명령을 실행하기 전에 파일이 잘리면 두 번째 방법도 빈 파일을 남겨두면 안 되나요?
답변1
문제는 파일 읽기가 시작 > example.txt
되기 전에 파일 쓰기가 시작된다는 것 입니다. shuf example.txt
그래서 아직 출력이 없기 때문에 example.txt
비어 있고, shuf
빈 파일을 읽어들이고, shuf
이 경우에는 출력이 없으므로 최종 결과는 비어 있게 됩니다.
다른 명령에서도 동일한 문제가 발생할 수 있습니다. > example.txt
파일 읽기를 시작하기 전에 파일을 종료 할 수 있습니다 . cat example.txt
이는 쉘이 이러한 작업을 수행하는 순서와 cat
실제로 파일을 여는 데 걸리는 시간에 따라 다릅니다.
이러한 문제를 완전히 방지하려면 shuf example.txt > example.txt.shuf && mv example.txt.shuf example.txt
.
아니면 함께 가도록 선택할 수도 있습니다 shuf example.txt --output=example.txt
.
답변2
콤보더 많은 유틸리티다음 명령이 있습니다 sponge
.
sponge reads standard input and writes it out to the specified file.
Unlike a shell redirect, sponge soaks up all its input before opening
the output file. This allows constricting pipelines that read from and
write to the same file.
이 방법으로 다음을 수행할 수 있습니다.
shuf example.txt | sponge example.txt
(안타깝게도 moreutils 패키지에는 util이라는 도구도 있는데 parallel
, 이는 gnu 병렬보다 훨씬 덜 유용합니다. parallel
moreutils 설치를 제거했습니다.)
답변3
넌 운이 좋아서 달릴 수 있을 뿐이야
cat example.txt | shuf > example.txt
example.txt
이 명령처럼 비어 있지 않습니다.
shuf example.txt > example.txt
리디렉션은 명령을 실행하고 동시에 파이프라인 구성 요소를 실행하기 전에 셸에서 수행됩니다.
-o
/ 옵션을 사용하는 것이 --output
가장 좋은 해결책이 될 수 있지만 shuf
(매우 약간의) 위험을 감수하고 싶다면 처리된 파일을 읽기 전에 잘리는 것을 방지하는 색다른 방법이 있습니다.
shuf example.txt | (sleep 1;rm example.txt;cat > example.txt)
제안해 주신 Ole에게 감사드립니다. 이 방법은 더 간단하고 빠릅니다.
(rm example.txt; shuf > example.txt) < example.txt
답변4
Ex 모드에서 Vim을 사용할 수 있습니다:
ex -sc '%!shuf' -cx example.txt
%
모든 행 선택!
명령 실행x
저장하고 닫습니다