私は以下を行うためにsedを使用しています。
- 一致パターン(例:で始まる行
#
) - 代替一致(例:
#
開始文字を空の文字に置き換え/削除) - stdoutで印刷する(例:使用しているように結果の置き換えをstdoutで印刷するなど
-i
) #
一致を削除する(例:行の先頭に文字を含む行全体を削除するなど)
これはファイルで実行されるため、フラグと一緒に使用すると、以下を使用しない限り、sed
stdoutに出力されません。-i
いたずら:
sed -i -e 's/^\(#\)/\1/w /dev/stdout' -e '/^#/d' test
名前付きファイルには、test
次のサンプルコンテンツが含まれています。
#this
#is
a
test
上記はすべてに適用されます。とは別に#
交換...ここに交換を実装することがあります(標準出力に印刷する前に文字を削除しようとしています)。
sed -i -e 's/^\(#\)//w /dev/stdout' -e '/^#/d' test
これは、行全体を印刷するのではなく削除することを除いて、\1
上記と似ています。//
#
問題は最後がうまくいかないことです。削除行の代わりに交換して印刷します。最初の方法は、置換を除くすべての操作で機能します(たとえば、#
行の先頭の記号を削除するなど)。
これがうまくいかないのはなぜですか(2番目の試み、最初の試みはうまくいきますが文字を削除しないことを除いて#
)
答え1
最初の式は、s/^\(#\)//w /dev/stdout
2番目の式と一致する可能性があるすべての項目を削除します。/^#/d
代わりに使用できます
sed -i -e '/^#/{s///w /dev/stdout' -e 'd}' test
前任者。
$ cat test
#this
#is
a
test
$ sed -i -e '/^#/{s///w /dev/stdout' -e 'd}' test
this
is
$ cat test
a
test
答え2
そしてGNU awk
:
awk -i inplace '{if (/^#/) {sub(/^#/, "");arr[++i]=$0;} else print}END{for (a in arr) print arr[a]}' input
オプション-i
またはソースライブラリが--include
含まれています。awk
inplace
-i
inplaceは、各入力ファイルの「in-place」編集を実行するGNU sedをエミュレートするオプションを拡張します。
if (/^#/)
で始まる行があることを確認してください#
。見つかったら、空の文字列にsub()
置き換えます。#
ここで置換を行い、$0
配列を作成します。arr
配列はEND
塊として印刷されるため、画面に印刷されます。印刷される追加の行(main
ブロック単位)はを介してファイルに送信されますinplace
。
$ awk -i inplace '{if (/^#/) {sub(/^#/, "");arr[++i]=$0;} else print}END{for (a in arr) print arr[a]}' input
this
is
$ cat input
a
test