1. 概要

このチュートリアルでは、Linuxでセパレーターを挿入してファイルを連結する方法を見ていきます。 単にファイルを連結したり、マージされたファイル間にセパレータを追加したりする必要がある場合があります。

3つのファイルfruits.txt、vegetables.txt、およびmesh.txtがあるとします。

$ cat fruits.txt 
Apple
Orange
Grapes
$ cat vegetables.txt 
Cabbage
Lettuce
Broccoli
$ cat meat.txt 
Pork
Beef
Mutton

そのためのさまざまな方法を見ていきます。

2. ループの使用

これらのファイルを連結するためにforループを使用して、単純なBashワンライナーを作成できます。 ループ内では、各ファイルを cat してから、出力を別のファイルにリダイレクトします。

これをどのように達成できるか見てみましょう。

$ for f in *.txt; do cat $f >> out.txt; done;
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

このコマンドを使用すると、ファイルの内容がout.txtファイルにマージされていることがわかります。

forループの使用は柔軟です。 ファイル間に新しい行を追加したり、別の区切り文字を挿入したりするなど、追加の処理を行うことができます。 そのためには、doキーワードとdoneキーワードの間にコマンドを追加する必要があります。

$ for f in *.txt; do cat $f >> out.txt; echo >> out.txt; done;
$ cat out.txt 
Apple
Orange
Grapes

Pork
Beef
Mutton

Cabbage
Lettuce
Broccoli

$

ここでは、 echoコマンドを使用して、ファイル間に新しい行を挿入しました。ご覧のとおり、完全に正常に機能しています。

3. findコマンドの使用

これは、上記のループソリューションに似ています。 for ループを使用する代わりに、findコマンドを使用してループをシミュレートできます。

これを実際に見てみましょう:

$ find *.txt -exec cat {} \; > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

すべてのファイルの内容がout.txtに連結されていることがわかります。 findコマンドはすべてのtxtファイルを検索し、 -exec オプションを使用して、catを生成できます。 out.txtファイル。

さらに-execオプションを追加して、ファイル間に改行を挿入できます

$ find *.txt -exec cat {} \; -exec echo \; > out.txt
$ cat out.txt 
Apple
Orange
Grapes

Pork
Beef
Mutton

Cabbage
Lettuce
Broccoli

$

同様に、xargsコマンドをfindコマンドと一緒に使用してファイルを連結することもできます

$ find *.txt | xargs -I{} sh -c "cat {}; echo" > out.txt
$ cat out.txt 
Apple
Orange
Grapes

Pork
Beef
Mutton

Cabbage
Lettuce
Broccoli

$

4. sedコマンドの使用

sed コマンドを使用して、テキスト入力ストリームを変更します。 sedコマンドを使用してファイルをマージする方法を見てみましょう。

$ sed '' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

上記のように、sedコマンドのデフォルトのアクションを使用してファイルをマージしました。

sed コマンドを使用して、各ファイルの後に改行を挿入する方法を見てみましょう。 ご存知のように、 sed コマンドには、$記号を使用してテキスト入力の終わりと行の終わりを識別するオプションがあります。

例を見てみましょう:

$ echo "test end of line" | sed '$s/$/\n/'
test end of line

$

ここでは、テキスト入力の後に新しい行が挿入されていることがわかります。 sedコマンド部分を分解してみましょう。

  • $ s –最後の行として範囲を選択します
  • $ –2番目の記号は行の終わりを表します
  • \ n –行末の代わりになります

したがって、ファイルの最後の行を取得し、行の終わりを見つけて、それを新しい行に置き換えます。

これを使用して、ファイル間に新しい行を挿入しましょう。

$ sed -e '$s/$/\n/' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli

$ 

上記の結果から、出力には新しい行が含まれていることがわかりますが、ファイルの最後にのみ含まれています。 各ファイルの後に新しい行が必要です。

これを修正するには、 表現オプション(-e)、 sedコマンドの-sオプションを使用できます。 これにより、sedでファイルを個別に処理できるようになります。 各ファイルの最後に新しい行が表示されます

それを見てみましょう:

$ sed -e '$s/$/\n/' -s *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes

Pork
Beef
Mutton

Cabbage
Lettuce
Broccoli

$

これで、各ファイルの終わりの後に出力に新しい行があることがわかります。 さらに、ファイル間に別の区切り文字が必要な場合は、sedパターンの改行の後にその区切り文字列を追加できます。

5. awkコマンドの使用

awk は、テキストの処理に使用される強力なコマンドラインユーティリティです。 AWK言語のprintおよび$0 キーワードを使用して、ファイルを連結します。

ファイルをマージする簡単な例を見てみましょう。

$ awk '{print $0}' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

上記のように、 print コマンドは値を表示し、 $0は処理中のレコードを表します。

したがって、コマンドは、指定されたファイルから各レコードを出力して、それらを連結します。

各ファイルの後にセパレータを挿入する方法を見てみましょう。 これにはENDキーワードを使用できます。 レコードの最後の行を識別します。

これを含めるようにコマンドを変更してみましょう。

$ awk '{print $0} END{printf "\n"}' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli

$

ご覧のとおり、改行が印刷されていますが、最後の行のみが印刷されています。 各ファイルの後に改行は出力されませんでした。

これを解決するために、AWK言語のFILENAME識別子を使用できます。 現在処理中のファイルの名前を保持します。 この識別子を使用して、ファイルが変更されたかどうかを確認してから、新しい行を挿入できます:

$ awk '{ if (FILENAME != file){ if (file) printf "\n"; file = FILENAME } } {print $0} END{printf "\n"}' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes

Pork
Beef
Mutton

Cabbage
Lettuce
Broccoli

$

これは少し面倒ですが、結果から、各ファイルの後に改行が挿入されていることがわかります。 もちろん、これをファイルの連結に使用するのはばかげています。 ただし、この演習では、awkコマンドについて1つか2つ学習しました。

6. 結論

このチュートリアルでは、ファイルを連結するさまざまな方法を見てきました。 また、それらをマージするときにセパレータを挿入する方法も確認しました。