Bash에서 여러 텍스트 파일을 단일 파일로 연결


305

디렉토리의 모든 * .txt 파일을 하나의 큰 텍스트 파일로 결합하는 가장 빠르고 실용적인 방법은 무엇입니까?

현재 cygwin이있는 창을 사용하고 있으므로 BASH에 액세스 할 수 있습니다.

Windows 셸 명령도 좋지만 하나가 의심됩니다.

답변:


537

그러면 all.txt에 출력이 추가됩니다.

cat *.txt >> all.txt

all.txt를 덮어 씁니다.

cat *.txt > all.txt

30
all.txt를 all.txt에 넣는 문제가 발생할 수 있습니다. 때때로 grep에이 문제가 있습니다. cat이 같은 동작인지 확실하지 않습니다.
rmeador

8
@rmeador 예, 사실입니다. all.txt가 이미 존재하면이 문제가 발생합니다. 이 문제는 출력 파일에 다른 확장자를 제공하거나 all.txt를 다른 폴더로 이동하여 해결됩니다.
Robert Greiner

2
고양이 * .txt >> tmp; mv tmp all.txt (그리고 all.txt가 미리 존재하지 않는지 확인)
Renaud

16
"인수 목록이 너무 깁니다"가 표시됩니다. 40,000 개 이상의 파일을 처리 할 수 ​​없습니다.
Matt

32
다음을 사용하여 인수 목록을 너무 길게 피하십시오.echo *.txt | xargs cat > all.txt
5heikki

145

지금까지 제공된 모든 솔루션에 대해 쉘은 파일이 연결되는 순서를 결정합니다. IIRC Bash의 경우 알파벳 순서입니다. 순서가 중요한 경우 파일 이름을 적절하게 지정하거나 (01file.txt, 02file.txt 등) 각 파일을 원하는 순서대로 지정해야합니다.

$ cat file1 file2 file3 file4 file5 file6 > out.txt

33

Windows 쉘 명령 type은 다음을 수행 할 수 있습니다.

type *.txt >outputfile

Type type명령은 또한 파일 이름을 stderr에 기록하는데, 이는 경로 >재 지정 연산자에 의해 캡처되지 않지만 콘솔에는 표시됩니다.


2
출력 파일을 원본 파일과 동일한 디렉토리에 넣으면 새 출력 파일도 두 번 결합하기 때문에 중복이 발생합니다.
CathalMF

26

Windows 셸 copy을 사용 하여 파일을 연결할 수 있습니다.

C:\> copy *.txt outputfile

도움에서 :

파일을 추가하려면 대상에 단일 파일을 지정하고 소스에 여러 파일을 지정하십시오 (와일드 카드 또는 file1 + file2 + file3 형식 사용).


초보자가 불행히도 넘어 질 수있는 부작용이없는 IMHO 가장 깨끗한 솔루션으로서 이것은 충분히 인정받지 못합니다 :-(
Grmpfhmbl

OP가 Bash를 요청했습니다.
Big Rich

2
질문을 읽었습니까? "Windows 쉘 명령도 좋을 것입니다 ..."
Carl Norum

8

이러한 방법 중 어느 것도 많은 파일에서 작동하지 않으므로주의하십시오. 개인적으로 나는이 줄을 사용했다 :

for i in $(ls | grep ".txt");do cat $i >> output.txt;done

편집 : 누군가가 코멘트에 말했듯이, 당신은 대체 할 수 $(ls | grep ".txt")와 함께$(ls *.txt)

편집 : @gnourf_gnourf 전문 지식 덕분에 glob 를 사용하는 것이 디렉토리의 파일을 반복하는 올바른 방법입니다. 결과적으로 같은 신성 모독적인 표현은 다음과 같이 $(ls | grep ".txt")대체되어야합니다 *.txt( 여기 의 기사 참조 ).

좋은 해결책

for i in *.txt;do cat $i >> output.txt;done

1
왜 안돼 for i in $(ls *.txt);do cat $i >> output.txt;done?
streamofstars

2
필수 구문 분석 링크와 다운 보트를 연결 ls | grep합니다 (심하게 나쁜 반 패턴이 있기 때문에 둘 이상의 다운 보트 가 필요합니다).
gniourf_gniourf

출력하기 전에 파일 이름으로 임의의 테스트 / 작업을 수행 할 수 있고 빠르고 쉽고 실용적이기 때문에 찬성했습니다. (내 경우에는 : * in i; echo -e "\ n $ i : \ n"; cat $ 1; done)
Nathan Chappell 's

는하지 않을까요 ls *.txt너무 많은 파일 (인수 목록이 너무 긴 오류)가있는 경우 실패?
라파엘 알메이다

6

쉘에서 가장 실용적인 방법은 cat 명령입니다. 다른 방법으로는

awk '1' *.txt > all.txt
perl -ne 'print;' *.txt > all.txt

1
대부분의 상황에서 정답입니다. 빈 줄 바꿈이없는 텍스트 파일 인 경우 위의 모든 cat방법을 사용하면 인접한 파일의 마지막 줄과 첫 줄을 연결합니다.
mootmoot

6

이 방법은 어떻습니까?

find . -type f -name '*.txt' -exec cat {} + >> output.txt

영업 이익은 파일이 같은 디렉토리에 말한다 때문에, 당신은 추가해야 할 수 있습니다 -maxdepth 1받는 find명령.
codeforester

1
허용 된 응답의 접근 방식이 실패하는 많은 파일과 함께 잘 작동
amine

아 내가이 플러스와 이중 리디렉션이 의미하는 것을 알고 싶습니다 ...
hello_earth

이것이 정답이어야합니다. 쉘 스크립트에서 제대로 작동합니다. 출력을 정렬하려면 다음과 유사한 방법을 사용하십시오.sort -u --output="$OUTPUT_FILE" --files0-from=- < <(find "$DIRECTORY_NAME" -maxdepth 1 -type f -name '*.txt' -print0)
steveH

3
type [source folder]\*.[File extension] > [destination folder]\[file name].[File extension]

예를 들어 :

type C:\*.txt > C:\1\all.txt

C : \ 폴더의 모든 txt 파일을 가져 와서 all.txt의 이름으로 C : \ 1 폴더에 저장합니다.

또는

type [source folder]\* > [destination folder]\[file name].[File extension]

예를 들어 :

type C:\* > C:\1\all.txt

폴더에있는 모든 파일을 가져 와서 C : \ 1 \ all.txt에 내용을 넣습니다.


0

당신은 이렇게 할 수 있습니다 : cat [directory_path]/**/*.[h,m] > test.txt

{}찾으려는 파일의 확장자를 포함하는 데 사용 하면 시퀀싱 문제가 있습니다.


0

all.txt를 all.txt로 분류하는 문제가 발생하면 all.txt가 있는지 확인하고 존재하는 경우 제거하십시오.

이처럼 :

[ -e $"all.txt" ] && rm $"all.txt"


cat *.txt > all.txt >존재하는 경우 all.txt 명령 덮어 쓰기는 >>기존 파일에 데이터를 추가
올렉 본다 렌코에게

-4

그 모든 것은 불쾌합니다 ....

ls | grep *.txt | while read file; do cat $file >> ./output.txt; done;

쉬운 물건.


6
여덟! 하지마 Dofind . -iname "*.txt" -maxdepth 1 -exec cat {} >> out.txt \;
Chinmay Kanchi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.