在 sed 中将 AWORD 或 BWORD 替换为 CWORD

在 sed 中将 AWORD 或 BWORD 替换为 CWORD

所以我有以下类型的随机网站列表:

   rapido21655bonk.a.sweetpotato.net
   rapido26230bonk.a.sourpotato.net
   rapido29926bonk.b.sourpotato.net
   rapido29926bonk.b.sweetpotato.net
   rapido30179bonk.a.sweetpotato.net
   rapido30648bonk.b.sourpotato.net
   rapido30761bonk.c.sweetpotato.net

现在我需要一个 sed 字符串来只留下数字,并取出其他所有内容。我所做的是: sed s/rapido//删除它的第一部分,但对于第二部分,我可以使用 sed 两次来删除它们,但我想知道是否可以使用某种or逻辑来删除它们一个 sed。我知道我可以使用 sed 来匹配a or b or cusing[abc]但我想要类似的东西来匹配整个单词。所以我之后做的是:

sed s/rapido//|sed s/bonk.[abc].sweetpotato.net//然后我会用 sourpotato.net 放另一个,但我似乎无法执行以下操作:

sed s/rapido//|sed s/bonk.[abc].(sweet|sour)potato.net// 这是行不通的。它给了我这个:( -bash: syntax error near unexpected token'`

仅替换号码是行不通的,因为有时我可能会得到类似rapido22452boonkers.red我想要保留在那里的东西。我只想删除 2 个替代方案sweetpotato.netOR sourpotato.net

[111@111 ~]$ sed s/rapido// sedster|sed 's/bonk.[abc].(sweetpotato|sourpotato).net//'
   21655bonk.a.sweetpotato.net
   26230bonk.a.sourpotato.net
   29926bonk.b.sourpotato.net
   29926bonk.b.sweetpotato.net
   30179bonk.a.sweetpotato.net
   30648bonk.b.sourpotato.net
   30761bonk.c.sweetpotato.net

答案1

如果您只想提取数字,可以使用 GNU 来执行此操作grep

$ grep -oP '\d+' file
21655
26230
29926
29926
30179
30648
30761

或者,使用 perl 进行移植:

$ perl -pe 's/[^\d\n]+//g' file
21655
26230
29926
29926
30179
30648
30761

或者sed

$ sed -nE 's/[^0-9]+//gp' file
21655
26230
29926
29926
30179
30648
30761

如果您需要更具体的输入数据,您可以尝试:

$ sed -nE 's/.*rapido([0-9]+)bonk\..\.(sweet|sour)potato.net.*/\1/p' file
21655
26230
29926
29926
30179
30648
30761

答案2

sed -r 's/([^0-9]*)([0-9]*)([^0-9]*)/\2/g'

你可以只保留中间的数字。这仅适用于扩展正则表达式,因此您需要-r选择sed.

其实用一下就够了

sed -r 's/([^0-9]*)([0-9]*)(.*)/\2/g'

\1这使用了用, , ...引用表达式部分的功能,\2然后您必须(...)在要引用的表达式部分周围使用括号。在上面的代码中,第二部分([0-9]*)将匹配中间的数字,您可以通过 来参考\2

编辑:正如 terdon 指出的,我们不需要捕获初始部分,因为我们不会再次使用它。所以

sed -n -r 's/[^0-9]*([0-9]+).*/\1/p'

足够。

总而言之,上面的命令只保留第一的输入行中的数字。

答案3

你的尝试

sed s/rapido// | sed s/bonk.[abc](sweet|sour)potato.net//

实际上非常接近,但你犯了两个错误。首先,您没有将命令放在引号内,因此bash解释了特殊字符“(”和“|”。(您收到 bash 错误消息的事实应该已经提示您这一点)。

第二个错误更加微妙。Sedgrep使用基本的正则表达式,其中只有几个字符 (。 * ^ $ [ ]) 有特殊含义。如果你想使用扩展正则表达式运算符 (| (){}),您需要在它们前面加上反斜杠。所以你的命令应该是这样的:

sed < t 's/rapido//' | sed 's/bonk.[abc].\(sweet\|sour\)potato.net//'

由于sed可以在一次运行中处理多个命令,因此您可以将其简化为

sed < t 's/rapido//; s/bonk.[abc].\(sweet\|sour\)potato.net//'

答案4

要删除除数字之外的所有内容,tr是一个解决方案:

x='21655bonk.a.sweetpotato.net
   26230bonk.a.sourpotato.net
   29926bonk.b.sourpotato.net
   29926bonk.b.sweetpotato.net
   30179bonk.a.sweetpotato.net
   30648bonk.b.sourpotato.net
   30761bonk.c.sweetpotato.net'
printf '%s\n' "$x" | tr -d '[:alpha:].' 
21655 26230 29926 29926 30179 30648 30761

或者

printf '%s\n' "$x" | tr -cd '0-9 ' 

相关内容