前の行に共通のテキストが含まれている場合、前の行と現在の行を維持する方法は?
次の基本ファイルがあります。
Hello_world
Anna
Frank
Jeremy
Hello_earth
Jessie
James
次の3つの出力ファイルが必要です。
出力ファイル1(以前のhelloの文字列のみ)
Hello_world,Anna
Hello_earth,Jessie
出力ファイル2(文字列のみがあり、以前のhelloはありません)
Frank
Jeremy
James
出力ファイル3(以前のhelloを持つ文字列のみ、古いhello行を持たない文字列にはHiが含まれています)
Hello_world,Anna
Hello_earth,Jessie
Hi,Frank
Hi,Jeremy
Hi,James
grepとawkを使ってみましたが、目的の結果は得られません。
答え1
追加の作業は次のとおりですawk
。
awk -v OFS=, '
/^Hello_/{
getline name
print $0, name > "file1"
print $0, name > "file3"
next
}
{
print > "file2"
s = s "Hi" OFS $0 ORS
}
END {
printf "%s", s > "file3"
}' < input
答え2
以下はGNU sedスクリプトです。完全なパターン空間ではなく、ファイルの最初の行にのみ追加するには、特殊な「W」(大文字のw)コマンドを使用します。これは「no_name」エッジケースに使用されます。下記をご覧ください。
#!/usr/bin/sed -nrf
/^Hello_/{
:new
$b no_name
N
/\nHello_/b no_name
b first_name
:no_name
s:^[^\n]+:&,:
W output_1.txt
W output_3.txt
s:^[^\n]+\n?::
/./b new
$b other_names
:first_name
s:\n:,:
w output_1.txt
w output_3.txt
}
/^Hello_/!H
${
:other_names
x
s:^\n::
w output_2.txt
/./s:^:Hi,:mg
w output_3.txt
}
"Hello_"キーワードの後に名前がないなど、いくつかの極端なケースをテストするためにサンプル入力ファイルにHello_foo\nHello_bar
。出力:
==> output_1.txt <==
Hello_world,Anna
Hello_earth,Jessie
Hello_foo,
Hello_bar,
==> output_2.txt <==
Frank
Jeremy
James
==> output_3.txt <==
Hello_world,Anna
Hello_earth,Jessie
Hello_foo,
Hello_bar,
Hi,Frank
Hi,Jeremy
Hi,James
答え3
Gnu linuxとfreebsdでテストされました。
sed '
/^Hello/!b1
N;s/\n/,/w file1
b
:1
w file2
s/^/Hi,/;H
$!d;x
s/^\n//
' file >file3
file1
標準出力と出力に2行を書き込みます。パターンスペースに1行を書き込んでfile2
追加し、最後にこれをstdoutとして出力しますfile3
。
答え4
予想される出力2と3は不明です。おそらく次のような意味のようです。
$ <hello paste -d, - - | sed -n '/Hello/p'
Hello_world,Anna
Hello_earth,Jessie
$ sed '/Hello/ d' hello
Anna
Frank
Jeremy
Jessie
James
$ (sed -n '/Hello/p' hello ;sed '/Hello/d' hello)
Hello_world
Hello_earth
Anna
Frank
Jeremy
Jessie
James
どこ:
$ cat hello
Hello_world
Anna
Frank
Jeremy
Hello_earth
Jessie
James