2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ShellScript: 2つのテキストファイルを縦に連結する.

Posted at

要約

2つのテキストファイルを連結する際,1つ目のファイルの末尾の改行がない場合,うまく連結できない.それを解決する方法として以下の3つをあげる.簡潔なのはその1のawkを用いた方法.

ファイル連結

その1: awk 1 file_1.txt file_2.txt
その2: echo "`cat file_1.txt`"'\n'"`cat file_2.txt`"
その3: cat file_1.txt <(echo "") file_2.txt

はじめに

 ShellScriptでよく使われるコマンドの1つにcatがある.cat はconcatenate(連結する)の略である[5].すなわち,cat の役割の一つにファイル連結がある.このことからもわかるように,ファイル連結は頻度が高い作業である.2つのファイルを連結をする際,1つ目のファイルの最終行に改行がない場合,すなわち1つ目のファイルの最終行がいわゆる "不完全な行" の場合,1つ目のファイルの最終行と2つ目のファイルの最初行が同じ行に並んでしまい,困ることがある[1][2][3].そこで,ここでは,上記問題を解決してファイル連結する方法を述べる.

環境

MacOS: 10.15.3
zsh: 5.7.1

準備

  • 最終行の末尾に改行がないファイルを作る(file_1.txt).
  • 最終行の末尾に改行があるファイルを作る(file_2.txt).
  • cat -eで末尾の改行有無を可視化する(改行があるときはダラー$が表示される).
  • file_1.txtとfile_2.txtとをcatで連結し,末尾の改行がない場合にうまくいかないことを確認する.
file_1.txt,最終行末尾に改行がない.
% cat -e file_1.txt
a$
b$
c%   #zshの場合,改行がない場合,色が反転した%が表示される
file_2.txt,最終行末尾に改行がある.
% cat -e file_2.txt
1$
2$
3$
  • 2つのファイルを連結.file_1.txtの最終行とfile_2.txtの最初行が同じ行になってしまっている.
file_1.txtとfile_2.txtとを連結
% cat file_1.txt file_2.txt
a
b
c1
2
3
  • 逆の順で連結.file_2.txtの末尾には改行があるのでうまく連結できる.
逆順で連結.

% cat file_2.txt file_1.txt
1
2
3
a
b
c%  #改行がないことを示すパーセント記号

最終行末尾の改行の有無を気にせず2つのファイルを連結する.

awkを用いて2つのファイルを結合

  • 簡潔.
  • 難点は,連結になぜcatではなくてawkを用いるのかわかりづらい.
  • awkは不完全な行に勝手に改行を加えてくれる[4].それを利用した方法.
awkを用いた方法
% awk 1 file_1.txt file_2.txt
結果
% awk 1 file_1.txt file_2.txt
a
b
c
1
2
3

echo を用いた方法

  • echoは自動的に改行される.それを利用する.

その1[6]

  • catで標準出力したものをバッククオートで囲み,それをさらにダブルクオートで囲み,それをechoで標準出力すると,その結果はcatで標準出力したものと同じ結果になる.\nで改行を加えて,2つ目のファイルにも同様の操作をする.
  • クオートでの囲い方の意味がわかりにくいのが難点.
echoでのやりかたその1
echo "`cat file_1.txt`"'\n'"`cat file_2.txt`"

その2[7]

  • サブシェルの標準入力<() [8]を用いる.
  • コードの意味が分かり易いのが利点.
  • 最終行に改行がある場合,空行が加わってしまうのが難点.ただし,その後の処理で空行を削除するのであればそれも解決できる.
echoでのやりかたその2
cat "file_1.txt" <(echo "") "file_2.txt"

考察,まとめ

  • 簡潔さという点でいうと,awkを用いた方法がよい.
  • コードのわかりやすさでいえば,サブシェルの標準入力<()を用いた方法がよい.

参考

[1]https://qiita.com/ngyuki/items/b55ce646cd84eb71c900
複数のファイルを終端に改行がなければ改行を追加して結合する - Qiita
[2]https://www.teradas.net/archives/25372/
catコマンドで連結するファイルの間に改行や文字列を追加する方法 | TeraDas
[3]https://www.linuxquestions.org/questions/linux-newbie-8/concatenate-two-files-with-a-new-line-character-between-them-829864/
[SOLVED] concatenate two files with a new line character between them
[4]https://qiita.com/BlackCat_617/items/00ea5db993ed31b56821
ShellScriptにおいて,テキストファイル末尾に改行を加える. - Qiita
[5]https://ja.wikipedia.org/wiki/Cat_(UNIX)
cat (UNIX) - Wikipedia
[6]http://sekitaka-1214.hatenablog.com/entry/2015/01/08/231918
2つのファイルの内容を改行を挟んで連結するbash - ほげほげ
[7]https://qiita.com/tkj/items/761cc6fcc6cba0159ab0
catでファイルを連結するとき・・ - Qiita
[8]https://fj.hatenablog.jp/entry/2016/03/06/170907
Bashの括弧 - 超ウィザード級ハッカーのたのしみ

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?