mecobalamin’s diary

人間万事塞翁が馬

https://help.hatenablog.com/entry/developer-option

sedの使い方

ファイルサイズが10 MBで中身が10万行を
超えるようなテキストファイルで、
列のラベルによって置換する文字を
変えるシェルスクリプトを書いた

例えばn列がhogehogeの場合、m列をaaaからbbbに変えて
n列がhugahugaの場合、m列をaaaからcccに変えるような
シェルスクリプト

まずはgrepで置換する行を選んで、
sedで置換する方法でやった
一行ずつ結果を出力を書き込むので
時間がかかる。。。。

#!/bin/bash

dir=`pwd`
filename=largetext.txt

filein=${dir}/${filename}
fileout=${dir}/rename_${filename}
filetmp=${dir}/tmp_${filename}

:> $fileout
while read line; do
        if echo $line | grep hogehoge > ./null; then
                echo $line | sed 's/aaa/bbb/' >> $fileout
        else
                echo $line >> $fileout
        fi
done < $filein

mv $fileout $filetmp

:> $fileout

while read line; do
        if echo $line | grep hugahuga > ./null; then
                echo $line | sed 's/aaa/ccc/' >> $fileout
        else
                echo $line >> $fileout
        fi
done < $filetmp

人に聞いたらこのサイトを教えてもらった
sedでこういう時はどう書く? - Qiita
sedで特定の文字列を含む場合の条件付ができる

sed -e '/[パターン]/s/[置換前]/[置換後]/'

パターンにマッチする場合に
置換前の文字列を置換後の文字列に置換する
オプションを-rに変えると拡張正規表現
パターンマッチができる

書き直したスクリプトがこれ

#!/bin/bash

dir=`pwd`
filename=largetext.txt

filein=${dir}/${filename}
fileout=${dir}/rename_${filename}
filetmp=${dir}/tmp_${filename}

cat ${filein} | sed '/hogehoge/s/aaa/bbb/' > ${fileout}

mv ${fileout} ${filetmp}
:> ${fileout}

cat ${filetmp} | sed -e '/hugahuga/s/aaa/ccc/' > ${fileout}
:> ${filetmp}

実行結果が分のオーダーから秒のオーダーまで短縮
スクリプトもスッキリしたし知らないって不幸

catの結果をsedで読み込んでいるけど
sedは引数にファイルを取れるので
もうちょっときれいに書けるかも

あと":"は何もしないってコマンドらしい

:> filename

で空のファイルを出力する