![如何 sed -e 's///' 除特定模式之外的所有内容?](https://linux22.com/image/36170/%E5%A6%82%E4%BD%95%20sed%20-e%20's%2F%2F%2F'%20%E9%99%A4%E7%89%B9%E5%AE%9A%E6%A8%A1%E5%BC%8F%E4%B9%8B%E5%A4%96%E7%9A%84%E6%89%80%E6%9C%89%E5%86%85%E5%AE%B9%EF%BC%9F.png)
如何用 sed 替换字符串中的所有内容(除了 % 和直接紧随其后的任何数字)?意思是,除了字符串之外的所有内容,例如:
%1
%1000
%55
ETC。
给定这种形式的字符串:
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
我只想得到%3
和%4
零件。数字最多可达999
.
答案1
$ sed 's/^.*\(%[0-9]\+\).*$/\1/' input
假设一行至多包含一个这些%123
标记,并且每一行都包含这样一个标记。
元\( \)
字符标记一个匹配组 - 然后通过\1
反向引用在替换中引用该匹配组。^
/$
匹配行的开头/结尾。
否则,您可以预先过滤输入,例如:
$ grep '%[0-9]\+' input | sed 's/^.*\(%[0-9]\+\).*$/\1/'
(当并非所有行都包含这样的标记时)
另一种变体:
$ sed 's/\(%[0-9]\+\)/\n\1\n/g' | grep '%[0-9]'
(当一行可能包含多个这些标记时)
以下是直接在每个标记之前和之后插入的换行符 - 在管道的第一部分中。然后该grep
部分删除所有非%123
标记行。
答案2
grep -o
在这种情况下你最好使用:
grep -oP '\B%[0-9]{1,3}\b' inputfile
假设您的版本grep
支持 Perl 兼容的正则表达式 ( -P
)。否则:
grep -o '\B%[0-9]\{1,3\}\b' inputfile
使用 GNU sed
,可以将空格音译为换行符并获得所需的行:
sed 'y/ /\n/' inputfile | sed '/^%[0-9]\{1,\}/!d'
答案3
使用时sed
几乎总是建议:
/address then/s/earch/replace/
有两个原因。第一个是多行/addressing/
更快 - 它仅针对寻找匹配,并且不必只选择行的一部分进行编辑,因此可以更快地缩小结果范围。
第二个原因是您可以对同一地址执行多个编辑操作 - 这使事情变得更加容易。
当然,在这种情况下,仅给出您显示的数据,这没有实际区别。不过,这就是我会做你问的事情的方式:
sed '/^[^%]*\|[^0-9]*$/s///g' <<\DATA
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
DATA
#OUTPUT
%3
%4
它只是选择所有字符非-%从行首开始的字符以及所有字符非数字的地址中行尾的字符,然后用s///
- 删除它们,就是这样。
在当前的形式下,如果您向其提供行,它可能会以意想不到的方式破坏数据不是包含一个%digit
组合 - 这就是为什么寻址很重要。如果我们稍微改变一下:
/%[0-9]/s/[^%]*\|[^0-9]*$//g
变得更安全和快点。
答案4
我的解决方案不使用 sed,而是使用带有扩展正则表达式和仅匹配选项的 grep。
$ cat file
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
$ cat file | grep -Eo '%[0-9]+'
%3
%4
在这种情况下使用 grep 比使用 sed 更简单。