次の入力ファイルがあります。
...
https://long-url/something?value1=999&something=xyz?value2=555
https://long-url/something?value1=534&something=xyz?value2=2312
https://long-url/something?value1=534&something=xyz?value2=233
https://long-url/something?value1=534
...
value1とvalue2をキャプチャしてcsvに出力し、一致しない行を削除したいと思います。
...
999,555
534,2312
534,233
...
値の取得に問題はありませんが、不要な行の削除に問題があります。
sed 's/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/\1,\2/g;/^[^0-9]\+/d' input-file
デフォルトでは期待どおりに/^[^0-9]\+/d
動作しません。私は数字で始まらないすべての行を削除すると思いましたが、代わりに次のような結果を提供します。
999,555
534,2312
534,233
私のsedバージョン:sed (GNU sed) 4.7
答え1
あなたは変える、次に削除:
sed -e 's/.../.../g' -e '/.../d'
/.../d
誤ってファイルコンテンツ内の他の項目と一致する可能性があるため、これはやや不安定です。
代わりに、置換によって影響を受けた行のみを印刷します。これは、(デフォルトの印刷を避けるために)行の末尾に-n
追加して、一致する行を印刷することによって行うことができます。p
これにより、2番目のステートメントは必要ありませんsed
。
sed -ne 's/.../.../gp'
g
1行に複数の一致が必要ないため、末尾も削除します。
sed -ne 's/.../.../p'
結果:
sed -ne 's/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/\1,\2/p' input-file
実行中:
$ sed -ne 's/.*value1=\([0-9]*\).*value2=\([0-9]*\).*/\1,\2/p' << EOF
https://long-url/something?value1=999&something=xyz?value2=555
https://long-url/something?value1=534&something=xyz?value2=2312
https://long-url/something?value1=534&something=xyz?value2=233
https://long-url/something?value1=534
EOF
出力
999,555
534,2312
534,233
答え2
あなたの式は^[^0-9]\+
数字以外の項目を1つ以上一致させます。つまり、空行には数値以外の項目が含まれていないため、一致しません。
個人的に私は次のようにします。
sed -e '/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/!d' \
-e 's//\1,\2/' input-file
まず、特定の正規表現と一致しないすべての行(空白行など)を削除します。 2番目の式は置換を実行します。空のパターンを使用すると(2番目の式の代替と同様に)、最近使用したパターンが再利用されます。
/g
パターンが入力行に一度だけ一致するようにするため、置換コマンドを終了する必要はありません。
答え3
一致させるには、/^[^0-9]\+/
行に少なくとも1つの文字を含める必要があります。つまり、空にすることはできません。
数字で始まる行を削除しないでください。
/^[0-9]/!d