此 sed 语法不会删除空行

此 sed 语法不会删除空行

我有这个输入文件:

...
https://long-url/something?value1=999&something=xyz?value2=555
https://long-url/something?value1=534&something=xyz?value2=2312


https://long-url/something?value1=534&something=xyz?value2=233
https://long-url/something?value1=534
...

我想捕获 value1 和 value2 并将它们输出为 csv,并删除任何不匹配的行:

...
999,555
534,2312
534,233
...

我在捕获值方面没有问题,但在删除任何不需要的行时遇到问题:

sed 's/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/\1,\2/g;/^[^0-9]\+/d' input-file

基本上,它/^[^0-9]\+/d没有按预期工作。我以为它会删除任何不以任何数字开头的行,但相反,它给了我:

999,555
534,2312


534,233

我的 sed 版本:sed (GNU sed) 4.7

答案1

您正在使用一个代替,后面跟着一个删除

sed -e 's/.../.../g' -e '/.../d'

这有点不稳定,因为您/.../d可能会意外地匹配文件内容中的其他内容。

相反,我只会打印受替代影响的行。这可以通过(以避免默认打印)来完成-n,然后添加p到行尾以打印匹配的行。这避免了第二次声明的需要sed

sed -ne 's/.../.../gp'

我还会删除尾随,g因为每行不需要多个匹配项:

sed -ne 's/.../.../p'

结果是:

sed -ne 's/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/\1,\2/p' input-file

行动中:

$ sed -ne 's/.*value1=\([0-9]*\).*value2=\([0-9]*\).*/\1,\2/p' << EOF
https://long-url/something?value1=999&something=xyz?value2=555
https://long-url/something?value1=534&something=xyz?value2=2312


https://long-url/something?value1=534&something=xyz?value2=233
https://long-url/something?value1=534
EOF

输出

999,555
534,2312
534,233

答案2

您的表达式^[^0-9]\+强制匹配至少一个非数字,这意味着空行不会匹配它,因为它们不包含非数字。

就我个人而言,我会按以下方式执行此操作:

sed -e '/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/!d' \
    -e 's//\1,\2/' input-file

这首先会删除与特定正则表达式不匹配的所有行(例如空行)。第二个表达式执行替换。当使用空模式时(如第二个表达式中的替换),将重新使用最近使用的模式。

请注意,您不需要/g在替换命令的末尾,因为您只希望每个输入行匹配一次模式。

答案3

要匹配/^[^0-9]\+/,该行必须至少包含一个字符,即不能为空。

只是不要删除以数字开头的行:

/^[0-9]/!d

相关内容