
수천 개의 작은 텍스트 파일을 하나의 큰 텍스트 파일로 결합하고 싶습니다. 구조가 다음과 같은 디렉토리에 있습니다 timestamp1/status.txt
. 예를 들어: 20130430133144/status.txt
. 지금까지 나는 그것을 알고 있다
cat */* > bigtextfile.txt
적은 수의 파일에 대해 작동합니다. 하지만 더 높은 숫자에도 효과가 있을까요? cat
에서 모든 파일의 내용을 수집한 다음 bigtextfile
. 그렇지 않으면 하나의 파일을 가져와서 에 추가한 bigtextfile
다음 다른 파일을 가져오는 등 의 다른 방법이 있어야 한다고 생각합니다 .
답변1
안에:
cat */* > bigtextfile.txt
쉘은 */*
(숨겨지지 않은) 일치하는 파일의 정렬된 목록으로 확장되고 cat
해당 파일 경로를 인수로 사용하여 실행됩니다.
cat
각 파일을 차례로 열고 파일에서 읽은 내용을 표준 출력에 씁니다. cat
한 번에 메모리에 데이터(몇 킬로바이트 정도)로 가득 찬 버퍼를 두 개 이상 보유하지 않습니다.
하지만 발생할 수 있는 문제는 인수 목록이 cat
너무 커서 시스템 호출의 인수 크기 제한에 도달한다는 것입니다 execve()
. 따라서 해당 파일 목록을 분할하고 cat
여러 번 실행해야 할 수도 있습니다.
이를 위해 사용할 수 있습니다 (여기서는 비표준 및 옵션 에 대해 xargs
GNU 또는 BSD 사용 ).xargs
-r
-0
printf '%s\0' */* | xargs -r0 cat -- > big-file.txt
( printf
쉘에 내장되어 있기 때문에 시스템 호출을 거치지 않으므로 execve
한계를 넘지 않습니다).
또는 find
파일 목록을 만들고 필요한 만큼 cat 명령을 실행하십시오.
find . -mindepth 2 -maxdepth 2 -type f -exec cat {} + > big-file.txt
또는 이식 가능:
find . -path './*/*' -prune -type f -exec cat {} + > big-file.txt
( 와는 반대로 */*
숨겨진 파일(및 숨겨진 디렉터리의 파일)을 포함하고 디렉터리에 대한 심볼릭 링크에서 파일을 찾지 않으며 파일 목록이 정렬되지 않습니다.)
최신 버전의 Linux에서는 다음을 수행하여 인수 크기 제한을 해제할 수 있습니다.
ulimit -s unlimited
cat -- */* > big-file.txt
를 사용하면 zsh
다음을 사용할 수도 있습니다 zargs
.
autoload zargs
zargs -- */* -- cat > big-file.txt
를 사용하면 ksh93
다음을 사용할 수 있습니다 command -x
.
command -x cat -- */* > big-file.txt
이들 모두 동일한 작업을 수행하며 파일 목록을 분할하고 cat
필요한 만큼 많은 명령을 실행합니다.
이번에도 내장 명령을 사용하여 제한을 ksh93
피할 수 있습니다 .execve()
cat
command /opt/ast/bin/cat -- */* > big-file.txt
답변2
아니요는 cat
쓰기를 시작하기 전에 모든 파일을 버퍼링하지 않습니다.
그러나 파일 수가 많은 경우 에 전달된 인수 수에 문제가 발생할 수 있습니다 cat
. 기본적으로 리눅스 커널은 고정된 수의 인수만 모든 프로그램에 전달되도록 허용합니다(값을 얻는 방법은 기억나지 않지만 대부분의 경우 수천 개입니다).
이 문제를 해결하려면 대신 다음과 같이 할 수 있습니다.
find -mindepth 2 -maxdepth 2 -type f -exec cat {} \; > bigtextfile.txt
이는 기본적으로 cat
에서 찾은 모든 파일에 대해 별도로 호출됩니다 find
.
답변3
파일 수가 너무 많으면 */*
너무 큰 인수 목록이 제공됩니다. 그렇다면 다음과 같은 조치를 취하면 됩니다.
find . -name "*.txt" | xargs cat > outfile
(아이디어는 를 사용하여 find
파일 이름을 선택하고 스트림으로 만드는 것입니다. xargs
이 스트림을 관리 가능한 조각으로 잘라서 에 제공하고 cat
이를 의 출력 스트림으로 연결한 xargs
다음 으로 들어갑니다 outfile
.)