26

我正在尝试匹配来自管道输入和/或文件的模式,然后从匹配的行中删除到文件的末尾,包括在内。我到处寻找,但似乎找不到适合我需要的表达方式。

以下表达式允许我删除到流的开头,包括匹配的模式:

sed -e '1,/Files:/d'

给定一些样本数据:

Blah blah blah
Foobar foo foo
Files:
 somefiles.tar.gz 1 2 3
 somefiles.tar.gz 1 2 3

-----THIS STUFF IS USELESS-----
BLEH BLEH BLEH
BLEH BLEH BLEH

运行上面的表达式会产生:

Files:
 somefiles.tar.gz 1 2 3
 somefiles.tar.gz 1 2 3

-----THIS STUFF IS USELESS-----
BLEH BLEH BLEH
BLEH BLEH BLEH

我想达到类似的效果,但方向相反。使用上一个表达式的输出,我想从-----THIS STUFF IS USELESS-----文件的末尾删除,包括在内。它应该产生(经过第一个表达式之后):

Files:
 somefiles.tar.gz 1 2 3
 somefiles.tar.gz 1 2 3

我也愿意使用任何其他工具,只要它在任何其他 POSIX 系统上可用并且不使用特定于版本(例如特定于 GNU)的选项。

实际文本可以在这里找到:http: //pastebin.com/CYBbJ3qr 注意从-----THIS STUFF IS USELESS-----到的变化-----BEGIN PGP SIGNATURE-----

4

5 回答 5

39

为什么不

 sed '/^-----THIS STUFF IS USELESS-----$/,$d' file

在您使用的范围表达式中,',$' 将指定“到文件末尾”

1 is first line in file, 
$ is last line in file.

输出

Files:
 somefiles.tar.gz 1 2 3
 somefiles.tar.gz 1 2 3


GNU sed你可以做

sed '/^-----THIS STUFF IS USELESS-----$/Q' file

whereQ类似于qquit 命令,但不打印匹配的行

于 2012-12-26T22:24:30.657 回答
5

与其试图弄清楚如何表达你不想要的东西,不如打印你想要的东西:

awk -v RS= '/Files:/' file

编辑:鉴于您修改后的输入:

awk '/^Files:$/{f=1} f; /^$/{f=0}' file

或者:

awk '/^Files:$/{f=1} f; /^-----THIS STUFF IS USELESS-----$/{f=0}' file

如果你更喜欢。

您也可以使用以下任何一种:

awk '/^Files:$/,/^-----THIS STUFF IS USELESS-----$/' file
sed '/^Files:$/,/^-----THIS STUFF IS USELESS-----$/' file

但它们以后很难扩展。

于 2012-12-26T22:26:04.193 回答
4
sed -e '/^-----THIS STUFF IS USELESS-----$/,$ d'
于 2012-12-26T22:26:11.890 回答
2

脏美工刀grep版:

cat your_output.txt | grep -B 99999999 "THIS STUFF IS USELESS" | grep -v "THIS STUFF IS USELESS"
于 2012-12-26T22:29:13.907 回答
0

这是一个正则表达式,我认为它可以满足您的要求:^(?:(?!Files:).)+|\s*-----THIS STUFF IS USELESS-----.+确保设置 dotall 标志。

演示+说明:http ://regex101.com/r/xF2fN5

您只需要运行这一个表达式。

于 2012-12-26T22:26:04.487 回答