如果上一行包含公共文本,如何保留上一行和当前行?
我有一个像这样的主文件:
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 的字符串,并包含 Hi 到没有上一行 hello 的字符串)
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
并输出。我们将单行写入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