3行の段落があり、行の上と下の単語を名前と一致させる必要があります。
現在のファイル
time toto
time toto name titi
time toto
time tutu
time tutu name tata
time tutu
私はこれが欲しい。
time titi
time titi name titi
time titi
time tata
time tata name tata
time tata
私は成功せずにこれを試しました。
awk 'NR>1{if(/name/) sub($2,$4,prev); print prev} {prev=$0}' fic.txt
解決策はありますか?
答え1
入力が実際に示されているのと同じであり、影響を受けるすべての文字列に正規表現のメタ文字や逆参照が含まれておらず、サブストリングまたは入力位置に望ましくない他の項目として表示されない場合は、次のようにします。
$ awk -v RS= -v ORS='\n\n' '{gsub($2,$6)}1' file
time titi
time titi name titi
time titi
time tata
time tata name tata
time tata
これが必要なものでない場合は、質問を編集してこれがうまくいかない場合を含む、より代表的な入力/出力の例を提供してください。
答え2
スクリプトが一致する行を見つけた場合は、前の行のみを変更します/name/
。現在の行と次の行も変更する必要があります。
このスクリプトは要求された変更を実行します。
awk '$3=="name" { search=$2; repl=$4; } # define new replacement
NR>1 {
sub(search,repl,prev); print prev; # modify and print previous line
}
{
prev=$0; # save line for next processing cycle
}
END {
sub(search,repl,prev); print prev; # process last line
}' fic.txt
もちろん、コメントを削除することもできます。
これを使用して印刷された入力ファイルの例:
time titi
time titi name titi
time titi
time tata
time tata name tata
time tata
別のバージョンは、フィールドの数が例の入力に示されているものと正確に一致し、各グループ内の最初と3番目の行が2番目の行から派生できるという前提条件に依存します。
awk 'NF>2 {
print $1,$4;
print $1, $4, $3, $4;
print $1, $4;
print "";
}' fic.txt
答え3
他の方法:
awk '{
if ( NF==2 ) {
pr=$0
}
if ( NF>2 ) {
split(pr,a) ; print a[1]FS$4
sub($2,$4) ; print
split(pr,a) ; print a[1]FS$4
}
if ( NF==0 ) { print }
}' fic.txt