ファイルを行で結合できるpasteコマンドが便利

tools

テキストファイルを行で結合したい

LinuxやmacOSで、catコマンドとかでテキストファイルを結合する操作は、日常よくありますね。

$ echo "A" > a.txt
$ echo "B" > b.txt
$ echo "C" > c.txt
$ cat a.txt b.txt c.txt
A
B
C

では、テキストファイルを行方向に結合するには...? 今回、この用途にpasteコマンドを使って便利でしたのでご紹介します。

pasteコマンドが使える例

例えば、挨拶の一覧が100個くらいあって、それを翻訳した表が欲しいとします。

各国語の挨拶の一覧
日本語 英語 簡体字中国語 アラビア語
ありがとう Thank you 谢谢你 شكرا لك
おはよう Good morning 早上好 صباح الخير
こんにちは Hello 你好 مرحبا
こんばんは Good evening 晚上好 مساء الخير
さようなら Goodbye 再见 وداعا
... ... ... ...

HTMLで書くと:

<table>
<caption>各国語の挨拶の一覧</caption>
<tr><th>日本語</th><th>英語</th><th>簡体字中国語</th><th>アラビア語</th></tr>
<tr><td>ありがとう</td><td>Thank you</td><td>谢谢你</td><td>شكرا لك</td></tr>
<tr><td>おはよう</td><td>Good morning</td><td>早上好</td><td>صباح الخير</td></tr>
<tr><td>こんにちは</td><td>Hello</td><td>你好</td><td>مرحبا</td></tr>
<tr><td>こんばんは</td><td>Good evening</td><td>晚上好</td><td>مساء الخير</td></tr>
<tr><td>さようなら</td><td>Goodbye</td><td>再见</td><td>وداعا</td></tr>
<tr><td>...</td><td>...</td><td>...</td><td>...</td></tr>
</table>

この表を、AWS CLIからAmazon Translate を使って作っていきます。

1. 日本語のテキストファイルの準備

日本語のテキストファイルを、1つのファイルに1つの文で作成します。

$ head greeting.*.ja.txt
==> greeting.1.ja.txt <==
ありがとう

==> greeting.2.ja.txt <==
おはよう

==> greeting.3.ja.txt <==
こんにちは

==> greeting.4.ja.txt <==
こんばんは

==> greeting.5.ja.txt <==
さようなら
...

2. 翻訳の作業

まず、テキストファイル: greeting.1.ja.txtの中身をAmazon Translateを使って翻訳する基本形です。AWS CLIを使って、日本語から英語への翻訳を指定するには、以下のようなコマンドになります。

aws translate translate-text --text `cat greeting.1.ja.txt` --source-language-code ja --target-language-code en

結果は、次のようなJSONで返されるので、 jqTranslatedText だけを取り出します。

{
    "TranslatedText": "Thank you",
    "SourceLanguageCode": "ja",
    "TargetLanguageCode": "en"
}

完成形は、HTMLのテーブルの1列になるので、前後に <td></td> を付加します。 これを、100個のテキストファイルについてループするので、最終形は以下のようになります。

$ for i in {1..100}; do aws translate translate-text --text `cat greeting.$i.ja.txt` --source-language-code ja --target-language-code en; done | jq -r '.TranslatedText'| sed -e "s/^/<td>/g" -e "s/$/<\/td>/g"

<td>Thank you</td>
<td>Good morning</td>
<td>Hello</td>
<td>Good evening</td>
<td>Goodbye</td>
...

これを、 en.txt に保存しておきます。

他の言語(arzh、...) についても同様に実施できます。細かいですが、macOS の sed では、sed: RE error: illegal byte sequence というエラーが出ました。この場合は GNU sedを使えばうまく動きます。

3. 結合します

こうして、各国語の挨拶の列ができました。これを paste コマンドで結合します!さらに、各行にて前後に <tr></tr> を付加します。

$ paste en.txt zh.txt ar.txt ...|gsed -e "s/^/<tr>/g" -e "s/$/<\/tr>/g"
<tr><td>Thank you</td>    <td>谢谢你</td>    <td>شكرا لك</td></tr>
<tr><td>Good morning</td> <td>早上好</td>    <td>صباح الخير</td></tr>
<tr><td>Hello</td>    <td>你好</td> <td>مرحبا</td></tr>
<tr><td>Good evening</td> <td>晚上好</td>    <td>مساء الخير</td></tr>
<tr><td>Goodbye</td>  <td>再见</td> <td>وداعا</td></tr>

できました!今までの cat だと英語の下に簡体字中国語がつながったりしますが、 paste だと横に繋がりますね! macOSの場合は、この出力を pbcopy コマンドに渡して、さっきの table 要素の間にペーストすれば、HTMLの表の完成です!

まとめ

paste コマンドって便利ですねってご紹介したかったのですが、内容の割には壮大な内容になった気がします。が、かなり便利なコマンドなので、何かのお役に立てば幸いです!