tanke25616429のアウトプット

IT技術の基本を勉強したことをアウトプットします。Linux、Kubernetes、クラウド中心です。百番煎じくらいだけど誰かの役に立てばそれはそれでうれしい。

シェルにおけるリダイレクト等を用いたテキストの処理

本記事

簡単にテキストファイルを作る方法として、エディタでテキストの編集したりechoを何回も実行しない方法があるので、それについて記載する。

catによるテキストファイルの作成

catとだけ打鍵すると、そのあと標準入力に記入した文字列が改行コードで区切られてそのまま標準出力に表示される。表示の上では入力した文字列と出力された文字列が混ざって見える。

# cat
1 ← 入力した文字列
1 ← そのまま出力
2
2
3
3

これを利用して、標準出力だけテキストファイルにリダイレクトすればよい。

# cat > test.txt
1 ← 標準入力だけが見えている
2
3 ← Ctrl+Dを押す
# cat test.txt
1
2
3

または<<EOFを使うこともできる(ヒアドキュメント)。これだとCtrl+Dでシグナルを送らなくてよい。

# cat <<EOF > test.txt
> a
> b
> c
> EOF
# cat test.txt
a
b
c

別に区切り文字はEOFでなくてもよいようである。

# cat <<SHELLCHOTTODEKIRU > test.txt
> x
> y
> SHELLCHOTTODEKIRU
# cat test.txt
x
y

変数展開したくない場合は区切り文字をクオーテーションで囲むとよい。

# cat <<EOF > test.txt
> $LANG
> EOF
# cat test.txt
en_US.UTF-8
# cat <<'EOF' > test.txt
> $LANG
> EOF
# cat test.txt
$LANG

teeと組合せる方法

teeコマンドで標準出力とファイルの両方に出力できる。

# date > test.txt
# cat test.txt
Sat Feb 27 13:28:26 JST 2021
# date | tee test.txt
Sat Feb 27 13:28:35 JST 2021
# cat test.txt
Sat Feb 27 13:28:35 JST 2021

なので、catとteeを組み合わせると記入終わったところ(EOFを入れたところ)でこれまで書いた内容が表示されるから一発で確認できる。

# cat <<EOF | tee test.txt
> a
> b
> EOF
a
b

cat以外の例

上で<<EOFの使い方を紹介したがもちろんcatの専売特許ではないので、別のコマンドでも利用できる。以下は文字列置換の例である。

# tr a A <<EOF
> abc
> EOF
Abc

なお、一行しかないなら<<<で文字列を指定することも可能(ヒアストリング)。

# tr a-e A-E <<<abcdefghij
ABCDEfghij

以下は入力した文字列の中から検索したい文字列にマッチする行だけを標準出力とファイルの両方に出力する例*1

# grep ABC <<EOF | tee test.txt
> ABC
> DEF
> GHI
> ABC
> EOF
ABC
ABC
# cat test.txt
ABC
ABC

Ctrl+DとCtrl+Cの違い

Ctrl+Cは処理を途中で終わらせるもの。Ctrl+DはEOFに対応し入力の終了を指示できるものである。 catでテキストを処理する場合、どちらでも大きな違いはない。catでは都度テキストファイルに書き込んでいくため、中断させても、正常に終了させても同じだからである。

# cat > test.txt
1 ← この後Ctrl+Cを押す
^C
# cat test.txt
1
# cat > test.txt
2 ← この後Ctrl+Dを押す
# cat test.txt
2

最後まで処理が正常に完了していないと正しい結果が得られないものでは動作が変わる。例えば行数をカウントするコマンドwcで試してみる。

# wc
1
2
3 ← この後Ctrl+Dを押す
      3       3       6 ← 結果が出力
# wc
1
2
3 ← この後Ctrl+Cを押す
^C ← 結果が出力されない
#

参考にしたもの

5 入力の終わりとコマンドの強制終了

qiita.com

*1:実際にはこんなことをしたいシーンは思い浮かばないので、あくまでこんなこともできるという例である