shuf file > file 명령은 빈 파일을 남기는데 비슷한 명령은 그렇지 않은 이유는 무엇입니까? [복사]

shuf file > file 명령은 빈 파일을 남기는데 비슷한 명령은 그렇지 않은 이유는 무엇입니까? [복사]

나는 이것이 다른 질문과 일종의 중복이라는 것을 알고 있습니다 (이 정렬 명령이 빈 파일을 제공하는 이유는 무엇입니까?) 하지만 주어진 답변을 바탕으로 질문을 확장하고 싶습니다.

주문하다

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 병렬보다 훨씬 덜 유용합니다. parallelmoreutils 설치를 제거했습니다.)

답변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
  1. %모든 행 선택

  2. !명령 실행

  3. x저장하고 닫습니다

관련 정보