ディレクトリ内のすべての(テキスト)ファイルを1つにマージする方法は?


89

1つのテキストの一部である14個のファイルがあります。それらを1つにマージしたいと思います。どうやってするか?

回答:


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オプションを設定できます)。
ジル

2
@ warren-young正しい、有用な警告コメント。しかし、実際のケースでは、順序に違いはありません(ファイルには、依存関係のないデータレコードを挿入する単純なSQLステートメントのみが含まれているため)。
イヴァン

2
ファイルの数が特定の制限を超えると、次のようなエラーが発生する可能性があることに注意してください-/ bin / cat:引数リストが長すぎる
-Nupur

1
@ ARA1307ファイルが既に存在する場合のみ。そうしないと、シェルがファイルを開いて書き込む前に、globが展開されます。そのような状況では良い点
マイケル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"が必要です-引用符なしでは失敗します。
ペティス

引用符の必要性は、findコマンドのバージョンによって異なります。特に、findとawkでは、Macを使用している場合に問題になります。両方のプログラムのバージョンは少し古いです。これまでのUbuntu、フェドーラ、DebianとCentOSの上には、引用符なしでスムーズに働いていた
3nrique0

パターン"*.csv"に一致するファイルが現在のディレクトリにない場合、引用符で囲まれていないバージョンが動作することを期待*findます。シェルはその後にリテラルを渡すからです。
-RJHunter


9

コマンド

$ cat * > merged-file

実際には、「マージされたファイル」を連結に含めて、暴走したファイルを作成するという望ましくない副作用があります。これを回避するには、マージしたファイルを別のディレクトリに書き込みます。

$ cat * > ../merged-file

または、マージされたファイルを無視するパターンマッチを使用します。

$ cat *.txt > merged-file

14
cat * > merged-file正常に動作します。グローブは、ファイルが作成される前に処理されます。merged-file既に存在する場合、cat(少なくとも私の場合)出力ファイルであることを検出し、それを読むことを拒否します。ファイルが既に存在し、パイプラインの後半にリダイレクトがある場合、明らかにそれを行うことはできません。
ケビン

catファイルが出力ファイルであるかどうかを検出する方法がありません。リダイレクトはシェルで行われます。cat標準出力にのみ印刷します。
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]はグロビングパターンとして機能しないことに注意してください。
クサラナナンダ

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

最後の行は、merge.txt(wmerge.txtではない!)も書き込むことに注意してください。w "merge.txt"を使用すると、ファイル名との混同を避けることができ、-nはサイレント出力に使用できます。

もちろん、ワイルドカードを使用してファイルリストを短くすることもできます。たとえば、上記の例のように番号付きファイルの場合、次のように中括弧で範囲を指定できます。

sed -n w"merge.txt" {1..3}.txt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.