디렉토리의 모든 (텍스트) 파일을 하나로 병합하는 방법은 무엇입니까?


89

14 개의 파일이 모두 한 텍스트의 일부입니다. 그것들을 하나로 병합하고 싶습니다. 그렇게하는 방법?

답변:


168

cat대부분의 사람들이 파일을 표준 출력으로 출력하기 위해 사용하더라도 기술적으로 ( "연결")해야 할 일입니다. 파일 이름을 여러 개 지정하면 파일 이름이 모두 순차적으로 출력 된 다음 새 파일로 리디렉션 할 수 있습니다. 모든 파일의 경우 그냥 사용하십시오 *(또는 /path/to/directory/*디렉토리에 없다면) 쉘은 모든 파일 이름으로 확장합니다

$ cat * > merged-file

15
인용 된 명령은 쉘 *이 "자연적인"순서로 확장되는 방식으로 번호가 매겨 질 경우 포스터가 원하는 대로만 수행 할 것입니다 . "file1.txt ... file9.txt ... file14.txt"가 있으면 file1? .txt가 file1.txt와 file2.txt 사이에서 정렬되므로 작동하지 않습니다. "file01.txt ... file09.txt ... file14.txt"로 이름을 바꿔야합니다. echo *확실하지 않다고 말 하십시오.
워렌 영

2
@Warren : 좋은 지적 (또는 zsh를 사용하고 numeric_glob_sort옵션을 설정할 수 있음).
Gilles

2
@ warren-young 정확하고 유용한 경고 설명. 그러나 실제로는 순서에 차이가 없습니다 (파일에는 종속성이없는 데이터 레코드를 삽입하는 간단한 SQL 문이 포함되어 있기 때문에).
Ivan

2
파일 수가 특정 제한을 초과하면-/ bin / cat : Argument list too long
Nupur

1
@ ARA1307 파일이 이미 존재하는 경우에만; 그렇지 않으면 쉘이 파일을 열기 전에 글롭이 확장됩니다. 그 상황에서 좋은 지적
Michael Mrozek

25

파일이 동일한 디렉토리에 있지 않은 경우 연결하기 전에 find 명령을 사용할 수 있습니다.

find /path/to/directory/ -name *.csv -print0 | xargs -0 -I file cat file > merged.file

파일이 이미 주문되어 있고 파일을 병합하여 분석하려는 경우 매우 유용합니다.


더 휴대 가능 :

find /path/to/directory/ -name *.csv -exec cat {} + > merged.file

파일 순서를 유지하거나 유지하지 않을 수 있습니다.


1
파일이 많으면 갈 수있는 방법입니다. "인수 목록이 너무 깁니다"오류가 발생하지 않습니다.
Мати Тернер

2
따옴표없이 -name * .csv 대신 -name "* .csv"가 필요합니다.
Peteris

따옴표의 필요성은 find 명령의 버전에 따라 다릅니다. 특히 find와 awk에서 Mac에있을 때 문제가됩니다. 두 프로그램의 버전은 약간 오래된 것입니다. 지금까지 우분투, 페도라, 데비안 및 CentOS에서는 따옴표없이 매끄럽게 작동했습니다
3nrique0

"*.csv"쉘이 리터럴 *을 전달하기 때문에 현재 디렉토리에 패턴 과 일치하는 파일이 없을 때 인용되지 않은 버전이 작동 할 것으로 예상한다 find.
RJHunter


9

명령

$ cat * > merged-file

실제로 병합에 '병합 파일'을 포함시켜 원치 않는 파일을 생성하는 바람직하지 않은 부작용이 있습니다. 이 문제를 해결하려면 병합 된 파일을 다른 디렉토리에 작성하십시오.

$ cat * > ../merged-file

또는 병합 된 파일을 무시하는 패턴 일치를 사용하십시오.

$ cat *.txt > merged-file

14
cat * > merged-file잘 작동합니다. 파일이 작성되기 전에 글로브가 처리됩니다. 경우 merged-file이미 존재, cat(광산은 적어도)는 출력 파일의 감지하고 그것을 읽을 거부합니다. 파일이 이미 존재하고 파이프 라인에서 나중에 리디렉션이 있으면 분명히 그렇게 할 수 없으므로 런 어웨이 파일을 얻습니다.
케빈

cat파일이 출력 파일인지 감지 할 방법이 없습니다. 리디렉션은 쉘에서 발생합니다. catstdout에만 인쇄합니다.
bfontaine

8

여기에서 다른 사람들이 말하듯이 ... 당신은 사용할 수 있습니다 cat

당신이 가지고 있다고 말할 수 있습니다 :

~/file01
~/file02
~/file03
~/file04
~/fileA
~/fileB
~/fileC
~/fileD

그리고 당신은 단지 원하는 file01file03fileAfileC:

cat ~/file01 ~/file02 ~/file03 ~/fileA ~/fileB ~/fileC > merged-file

또는 중괄호 확장을 사용하십시오.

cat ~/file0{1..3} ~/file{A..C} > merged-file

또는 더 멋진 버팀대 확장을 사용하는 경우 :

cat ~/file{0{1..3},{A..C}} > merged-file

또는 for루프 를 사용할 수 있습니다 .

for i in file0{1..3} file{A..C}; do cat ~/"$i"; done > merged-file

1
문자열 [01-03]은 글 로빙 패턴으로 작동하지 않습니다.
Kusalananda

0

pattern파일을 지정하고 다음과 같이 모든 파일을 병합 할 수 있습니다 .

cat *pattern* >> mergedfile

0

또 다른 옵션은 sed입니다.

sed r 1.txt 2.txt 3.txt > merge.txt 

또는...

sed h 1.txt 2.txt 3.txt > merge.txt 

또는...

sed -n p 1.txt 2.txt 3.txt > merge.txt # -n is mandatory here

또는 리디렉션없이 ...

 sed wmerge.txt 1.txt 2.txt 3.txt

마지막 줄은 또한 wmerge.txt가 아닌 merge.txt입니다. w "merge.txt"를 사용하여 파일 이름과 혼동을 피하고 자동 출력의 경우 -n을 사용할 수 있습니다.

물론 와일드 카드를 사용하여 파일 목록을 줄일 수도 있습니다. 예를 들어, 위 예제에서와 같이 번호가 매겨진 파일의 경우 다음과 같이 중괄호로 범위를 지정할 수 있습니다.

sed -n w"merge.txt" {1..3}.txt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.