シナリオは、シェルスクリプトで最後に表示された単語をコメントアウトしたいということですsed
。
temp.sh
以下があるとしましょう。
Abc 123 Abc
Sdf 2
Abc
Abc
Utyr
Qww
Abc
私は最後のインスタンス(行の先頭に発生)を次のように置き換えたいと思います。#Abc
結局のところ、結果は次のようになります。
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
答え1
ファイルを元に戻すには、最初のファイルをコメントアウトしてからファイルを元に戻します。
$ tac temp.sh | sed '0,/^Abc/{s/^Abc/#&/}' | tac
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
これは、「行0から始まり、最初の行が一致するまで続行し、その行のみがこの/^Abc/
場合()に一致するものにAbc
置き換えられることを意味します。ありがとうございます。#
#
Abc
この回答。
これにはtac
GNUツールとGNU実装が必要ですsed
。
ソースファイルを変更するには、次のようにします。
tac temp.sh | sed '0,/^Abc/{s/^Abc/#&/}' | tac > temp1.sh &&
mv temp1.sh temp.sh
またはPerlでは:
$ tac temp.sh | perl -pe 'next if $k; $k++ if s/^Abc/#$&/ ' | tac
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
ソースファイルを変更するには、次のようにします。
tac temp.sh | perl -pe 'next if $k; $k++ if s/^Abc/#$&/ ' | tac> temp1.sh &&
mv temp1.sh temp.sh
または使用ステファンの純粋なperl
アプローチまたは先行きれいなsed
人、両方とも-i
生ファイルを編集するために使用されます。
答え2
$ sed -e 'H; $!d' -e 'g; s/\n\(.*\n\)\(Abc\)/\1#\2/' file
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
これにより、ファイル全体が予約済みスペースに読み込まれ、変更されたsed
後に変更されたテキストが出力されます。
最初の2つのsed
式をH
合計し、$!d
各行を予約済みスペースに追加してから、次のループにジャンプします(入力の最後の行にない場合)。
このg
コマンドは最後の行に対して実行され、予約済みスペースの内容を取得します。その後、置換はその中の最初の改行を削除し(最初の行を空の予約スペースに追加し)、#
最後の改行の前にAbc
文字を挿入します。
私達は得ることを保証します最後 Abc
改行文字以降は.*
欲が多いので、できるだけ一致するようになります。
-i
ファイルを内部で編集できます(sed
BSDにsed
必要なGNUを使用-i '.bak'
)。
sed -i'.bak' -e 'H; $!d' -e 'g; s/\n\(.*\n\)\(Abc\)/\1#\2/' file
ed
編集者と一緒に:
$ printf '%s\n' '1;?^Abc?;s//#&/' ,p Q | ed -s file
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
ed
これは本質的に単一の編集コマンドを使用して編集を実行します1;?^Abc?;s//#&/
。このコマンドは、最初にカーソルをファイルの最初の行(1
;Abc
文字列が最後の行にある場合は必要です)に移動し、ファイル^Abc
で最後に一致する正規表現(?^Abc?
)を検索します。見つかったら、#
見つかった行の先頭に文字(s//#&/
;これは最後に一致した正規表現を再利用し、&
後で行の一致部分を挿入するために使用されます)を挿入します#
。
末尾,p
とQ
コマンドはバッファ全体を標準出力として印刷し、無条件に終了します。
答え3
含むawk
(パイプを除く):
awk -v str=Abc '
NR==FNR{if ($0 == str) nr_str=NR; next}
{print (FNR == nr_str) ? "#"$0 : $0}
' file file
出力
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
答え4
使用awk
:
ファイルを元に戻すには、thenawk
関数を使用します。sub()
後でファイルを再度反転すると、期待した出力が得られます。
$ tac file |
awk '/^Abc/ && (!found){sub(/^Abc/, "#Abc"); found++}1' |
tac
出力
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
パイプがない場合:
$ awk '
BEGIN{rec_rep=""; rec_last=""}
{if (/^Abc/){
if (rec_rep) print rec_rep;
rec_rep = $0;
sub(/^Abc/, "#Abc");
rec_last = $0;
}
else { rec_rep = ((rec_rep) ? rec_rep ORS : "") $0;
rec_last = ((rec_last) ? rec_last ORS : "") $0 }
}
END{print rec_last}' file