StackOverflow에서 다음 질문에 대해 겉보기에 모순되는 두 가지 답변을 찾았습니다.
- 수백 개의 디렉터리에 있는 수천 개의 텍스트 파일을 연결합니다(일부 구조는 유지하면서).
- Unix 찾기, 실행 및 고양이를 사용하여 하위 디렉터리의 파일을 단일 파일로 연결하는 방법은 무엇입니까?
첫 번째 질문에 대한 가장 좋은 대답은 다음과 같습니다.
find . -name *.txt -print0 | xargs -0 cat >> out.txt
두 번째 질문에 대한 가장 좋은 대답은 다음과 같습니다.
find . -name *.txt -print0 | xargs -0 cat > out.txt
내가 아는 한, 첫 번째 것은 >>
(추가) 연산자를 사용하기 때문에 정확하지만 두 번째 것은 >
출력을 파일로 리디렉션하는 연산자를 사용하기 때문에 정확하지 않습니다. 그러나 두 번째 답변은 더 많은 표(10)를 얻었으며 댓글 없이도 승인됩니다. 둘 다 정답인가요? 왜? 그렇다면 이 두 연산자를 갖는 목적은 무엇입니까?
답변1
두 번째 예:
find . -name '*.txt' -print0 | xargs -0 cat > out.txt
완전히 합법적인 out.txt
파일은 실행될 때마다 다시 생성되고 첫 번째 파일 out.txt
실행이 연결됩니다. 그러나 두 명령 모두 본질적으로 동일한 작업을 수행합니다.
이 질문은 혼란스럽습니다 xargs -0 cat
. 사람들은 리디렉션이 out.txt
명령의 일부라고 생각하지만 그렇지 않습니다. 리디렉션은 xargs -o cat
STDIN을 통해 입력을 받은 다음 해당 출력을 단일 스트림으로 STDOUT에 출력한 후에 발생합니다. 이는 xargs
출력이 아닌 최적화된 파일의 디렉터리입니다.
여기 제가 말하는 내용의 예가 있습니다. pv -l
와 파일 출력 사이에 하나를 삽입 하면 cat이 몇 줄을 썼는지 알 수 있습니다.xargs -0 cat
out.txt
예
이를 보여주기 위해 10,000개의 파일이 포함된 디렉터리를 만들었습니다.
for i in `seq -w 1 10000`;do echo "contents of file$i.txt" > file$i.txt;done
각 파일은 다음과 유사합니다.
$ more file00001.txt
contents of file00001.txt
출력 pv
:
$ find . -name '*.txt' -print0 | xargs -0 cat | pv -l > singlefile.rpt
10k 0:00:00 [31.1k/s] [ <=>
singlefile.rpt
보시다시피, 내 파일에는 10,000줄이 기록되어 있습니다. 출력 블록이 전달 되면 xargs
감소할 행 수가 표시되는 것을 볼 수 있습니다 pv
.
답변2
그렇다면 이 두 연산자를 갖는 목적은 무엇입니까?
간단합니다. 다양한 사용 사례가 있기 때문입니다. 때로는 대상 파일을 먼저 크기 0으로 자르는 것이 유용할 수도 있고 때로는(예: 로그 파일) 데이터를 파일에 추가하는 것이 더 합리적일 수도 있습니다.
이 경우 추가하는 것은 의미가 없습니다. "시작 부분에 데이터가 있고 끝에 선택한 파일의 내용이 포함된 파일"이 아니라 선택한 파일과 정확히 동일한 내용을 가진 파일이 필요합니다.
답변3
나는 두 번째를 선택하겠습니다. Enter 키를 누르면 stdout의 리디렉션이 bash에 의해 캡처되므로 find/xargs의 각 줄에 대해 새로운 리디렉션을 만드는 것과는 다릅니다(아마도 그들의 아이디어였을 것입니다). 그렇지 out.txt
않다면 동일해야 합니다. 이미 데이터가 있는 경우 두 번째 데이터는 적어도 파일을 알려진 콘텐츠(즉, 콘텐츠 없음)로 재설정합니다.