sedの使い方忘れないように
sedを使いこなしたいと思いつつ、多機能すぎてついつい忘れてしまう。
基本の使い方のチートシート的な。使っているのはMacの標準で入っているBSD系のsed。
# パイプつなぎ ~ $ echo It is sunny today. | sed 's/sunny/rainy/g' It is rainy today. # 複数つなげる時は -e ~ $ echo It is sunny today. | sed -e 's/sunny/rainy/g' -e 's/rainy/cloudy/g' It is cloudy today. # ファイルをインプットとする ~ $ cat weather.txt It is sunny today. ~ $ sed -e 's/sunny/rainy/g' weather.txt It is rainy today.
ちょっと便利な使い方
特定の文字列が出てきた時、それを抽出したい。
例えば、uniqueIDという文字列が出てきた時、それに続くIDを取得したいケース。
- 前提1:行によって要素数が異なるため、単純にカンマ区切りで抽出とかはできない
- 前提2:uniqueIDは10桁の固定とし、1行内にuniqueIDは1回しか出てこないとする
# パイプつなぎ ~ $ echo \"time:2020-08-01\",\"uniqueID\":\"ABCDEFGHIJ\",\"name\":\"hoge\" | sed -e 's/^.*uniqueID":"\(.\{10\}\).*$/\"uniqueID\":\"\1\"/' "uniqueID":"ABCDEFGHIJ" # ファイルをインプットとする(マッチしないする行も出力してしまうので最後にgrepしている。grepせんでもsedだけでできそうな気もするが...) ~ $ cat log "time:2020-08-01","uniqueID":"ABCDEFGHIJ","name":"hoge" "time:2020-08-01","wanwan":"inu","nyannyan":"neko" "time:2020-08-01","uniqueID":"WANNYANWAN","wanwan":"inu" ~ $ sed -e 's/^.*uniqueID":"\(.\{10\}\).*$/\"uniqueID\":\"\1\"/' log | grep uniqueID "uniqueID":"ABCDEFGHIJ" "uniqueID":"WANNYANWAN" # やってること # "uniqueID:"という文字列が出てきた時、その後に続く10文字を取得する # "uniqueID:"という文字列以降全てを、"uniqueID:" + 取得した10文字に置換する
()でグループ化して\1
でマッチしてる部分を取得しているとことが肝。例えばこんなふうに使える。
# グループに一致した値が`\1`に入る ~ $ echo abcdefghij | sed -e 's/^.*def\(.\{1\}\).*$/\1/g' g # グループが複数ある場合、採番が振られる ~ $ echo abcdefghij | sed -e 's/^.*def\(.\{1\}\)\(.\{1\}\).*$/\1 \2/g' g h
これだけ覚えていればいろいろできそうだぞ(できない)