Bashで複数のテキストファイルを単一のファイルに連結する


305

ディレクトリ内のすべての* .txtファイルを1つの大きなテキストファイルに結合する最も迅速で実用的な方法は何ですか。

現在、cygwinでWindowsを使用しているため、BASHにアクセスできます。

Windowsシェルコマンドもいいですが、あるとは思いません。

回答:


537

これにより、出力がall.txtに追加されます

cat *.txt >> all.txt

これはall.txtを上書きします

cat *.txt > all.txt

30
all.txtをall.txtにキャットする問題に遭遇するかもしれません...私はgrepでこの問題を抱えていることがあります。猫が同じ動作をするかどうかはわかりません。
rmeador 2010年

8
@rmeadorはい、そうです。all.txtがすでに存在する場合は、この問題が発生します。この問題は、出力ファイルに異なる拡張子を付けるか、all.txtを別のフォルダーに移動することで解決されます。
Robert Greiner、2010年

2
cat * .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
出力ファイルを元のファイルと同じディレクトリに配置すると、新しい出力ファイルが2回結合されるため、複製が発生することに注意してください。
CathalMF 2013年

26

Windowsシェルcopyを使用してファイルを連結できます。

C:\> copy *.txt outputfile

ヘルプから:

ファイルを追加するには、宛先には単一のファイルを指定しますが、ソースには複数のファイルを指定します(ワイルドカードまたはfile1 + file2 + file3形式を使用)。


これは基本的に副作用がなく、初心者が
つまづく可能性のあるIMHOの

OPはBashを要求しました。
ビッグリッチ

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
必須のParsingLsリンクと反対投票(そして、非常ls | grepに悪いアンチパターンであるため、複数の反対投票に値します)。
gniourf_gniourf

出力前にファイル名で任意のテスト/操作が可能であり、迅速かつ簡単で練習に適しているため、私から賛成票をもらいました。(私が欲しかったのは:for i in *; do echo -e "\ n $ i:\ n"; cat $ 1; done)
Nathan Chappell

ls *.txtファイルが多すぎると失敗しませんか(引数リストが長すぎるエラー)。
Rafael Almeida

6

シェルの最も実用的な方法はcatコマンドです。他の方法には、

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

1
これは、ほとんどの状況で正しい答えになるはずです。空の新しい行がないテキストファイルがある場合、上記のすべてのcat方法を使用すると、隣接するファイルの最後の行と最初の行が連結されます。
mootmoot 2016年

6

このアプローチはどうですか?

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

OPはファイルが同じディレクトリにあると言っているので-maxdepth 1findコマンドに追加する必要があるかもしれません。
codeforester 2017

1
受け入れられた返信のアプローチが失敗する多数のファイルでうまく機能します
アミン

ああ、このプラスとダブルのリダイレクトが何を意味するか知っていればいいのに…
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を上書き>>し、既存のファイルにデータを追加します
Oleg Bondarenko

-4

それはすべて厄介です...

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

簡単なもの。


6
いいね!それをしないでください。実行find . -iname "*.txt" -maxdepth 1 -exec cat {} >> out.txt \;
Chinmay Kanchi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.