🎞️

grep -fでファイルに出力した内容を検索しようとしてよくするミス

2021/05/23に公開

grepさん。いつもお世話になっております。

grep 好きですよね。grep

私も日々の運用業務でよくお世話になっています。


客「このid5個を含めた3000レコード分のファイルをS3に配置したんですけど、DBに取り込まれていますか?」

僕「DBに取り込まれていないですね・・・エラーも出ていないようなので元ファイルの方確認しますね」


こんな感じでテキストに出力したid(compare.txt)が元ファイル(org.csv)に記載されているか確認したいとします。

そんな時 grep -f compare.txt org.csv とすれば一発でcompate.txtに記載された一覧と合致する行を抽出してくれます。

しかしどうにもうまくいかない・・・

私がよくやっているミスと解決法を記載しておきます。

以下のテキストを使っているとしてください。

一覧ファイル(org.csv)

# org.csv
id,name
1,test1
2,test2
3,test3
4,test4
5,test5
6,test6
7,test7
8,test8
9,test9
10,test10
11,test11
12,test12
13,test13
14,test14
15,test15
16,test16
17,test17
18,test18
19,test19
20,test20
21,test21
22,test22
23,test23
24,test24
25,test25
26,test26
27,test27
28,test28
29,test29
30,test30

比較したいファイル(compare.txt)

# compare.txt
test10
test21
test25
test28

# 最終行に改行が入っているのに注意

よくやるミス

文字コード・改行コードが違う

その1です。
特に顧客の非エンジニアの方はエクセルに記載した一覧を下さいます。
(org.csv.xlsmみたいな・・・)

そんな時は文字コード・改行コードを確認し、合わせるのを忘れないようにしましょう。
(ありがちなのが改行コードを変換し忘れるとか・・・)

私はMacを使っているので、Windows機から頂いたデータは特に注意ですね。
(Macでもエクセルファイルの時点で)

# 文字コード確認
nkf -g org.csv
# utf8・改行LFに変換
cp org.csv bk_org.csv && nkf -Luw --overwrite org.csv

比較用ファイルに空行が含まれている

文字コードも直したので、一発compare.txt の内容が org.csvに何行含まれているか確認しようとします。

grep -f compare.txt org.csv | wc -l
> 32

ん・・・
なんで全行マッチすることになっているんだ!!

と思ったのですがここで man コマンドで grepのマニュアルを見てみると

-f file, --file=file
             Read one or more newline separated patterns from file.  Empty pattern lines match every input line.  Newlines are not considered part of a pattern.  If file is empty, nothing is
             matched.

Empty pattern lines match every input line.

空行は全ての行にマッチします。

とはっきり書いてくださっています。

だって POSIXの制約でテキストファイルの最終行は改行にしましょう って死ぬほど言われていたから・・・

ということで不要な改行だけの行は削除して比較をします

cp compare.txt bk_compare.txt && sed '/^$/d' bk_compare.txt > compare.txt && grep -f compare.txt org.csv | wc -l
> 4

Discussion