bashでテキストファイルの各行をforで処理する方法

bashでforを使う

テキストファイル(csvやtsvなど)の行・列に対して、bashのfor文で1行毎に処理する方法を紹介します。

この記事ではサンプルとして、各行にファイル名が書かれていてそのファイルに対して処理するスクリプトを作成します。

ほぼ自分のための備忘録です。

処理はとても簡単なのですが、こういう処理は久々に使おうとすると忘れてしまっているんですよね、、、

行ごとにbashのforで処理する

サンプルファイル

各行にファイル名が記載されています。

$ cat list.txt
a.txt
b.txt
c.txt

bashで1行毎処理する

$ cat test.sh
#!/bin/bash
for line in `cat list.txt`; do
        echo $line
done;

$ bash test.sh
a.txt
b.txt
c.txt

各行の値が出力されていることが確認できます。

よく使う例

各行のファイルをコピーしたりリネームするときに利用します。

下記の例では、list.txtに記載されたファイルがcopyディレクトリにコピーされていることが確認できます。

$ cat test.sh
#!/bin/bash
for line in `cat list.txt`; do
        `cp ${line} ./copy/`
done;

$ tree
.
├── a.txt
├── b.txt
├── c.txt
├── copy
├── list.txt
└── test.sh

$ bash test.sh
$ tree
kei-pc% tree
.
├── a.txt
├── b.txt
├── c.txt
├── copy
│   ├── a.txt
│   ├── b.txt
│   └── c.txt
├── list.txt
└── test.sh

CSVファイルの任意の列の行を処理する

CSVファイル内の特定の列に対して、各行をforで処理する方法です。

上記のcatコマンドをcutコマンドに変更するだけで実現できます。

cutコマンドがわかる方には簡単だと思いますが、-fオプションで列を指定して、-dで区切り文字を指定しています。

$ cat list.csv
1,a,x
2,b,y
3,c,z

$ cat test.sh
#!/bin/bash
for line in `cut -f 2 -d ',' list.csv`; do
        echo $line
done;

$ bash test.sh
a
b
c

まとめ

この記事ではファイル内の文字列を行ごとにforで処理するためのシェルスクリプトを紹介しました。

一括でリネームしたり、コピーしたりするときには必須の構文なので、備忘録として残しておきます。