![仅 Grep 左括号旁边的 3 个字符](https://linux22.com/image/194567/%E4%BB%85%20Grep%20%E5%B7%A6%E6%8B%AC%E5%8F%B7%E6%97%81%E8%BE%B9%E7%9A%84%203%20%E4%B8%AA%E5%AD%97%E7%AC%A6.png)
我有这样的文本,我只想 grep 开括号旁边的 3 个字符。请帮忙。
condition: s(XXX_ygh_ghj_jui,00.05) | s(DFG_GHH_CN_GJ_YUI_UYT_UIJ,00.05)
condition: s(GYZ_ygh_ghj_jui,00.05) | s(TYU_GHH_CN_GJ_YUI_UYT_UIJ,00.05)
condition: s(UFG_ygh_ghj_jui,00.05) | s(QWE_GHH_CN_GJ_YUI_UYT_UIJ,00.05)
condition: s(JTH_ygh_ghj_jui,00.05) | s(YUT_GHH_CN_GJ_YUI_UYT_UIJ,00.05)
我想要的o/p是
XXX DFG
GYZ TYU
UFG QWE
JTH YUT
答案1
GNUgrep
可以做到这一点,但如果您使用grep
,它会将匹配拆分为多行:
$ grep -oP '(?<=\()...' file
XXX
DFG
GYZ
TYU
UFG
QWE
JTH
YUT
正如 @kusalandanda 在评论中建议的那样,您可以将它们放在一行上paste
,但这只有在您有的情况下才有效确切地每行两个匹配。不多也不少:
$ grep -oP '(?<=\()...' file | paste -d ' ' - -
XXX DFG
GYZ TYU
UFG QWE
JTH YUT
我会使用类似sed
or 的东西perl
。这些解决方案可以处理每行 1 个、2 个或更多匹配项:
$ sed 's/[^(]*(\(...\)[^(]*/\1 /g' file
XXX DFG
GYZ TYU
UFG QWE
JTH YUT
或者
$ perl -lne '@m=(/\((...)/g); print "@m"' file
XXX DFG
GYZ TYU
UFG QWE
JTH YUT
答案2
$ sed 's/.*(\(...\).*(\(...\).*/\1 \2/' file
XXX DFG
GYZ TYU
UFG QWE
JTH YUT
该sed
表达式匹配整行输入,但收集两个左括号后面的三个字符。然后,该行将被两组收集的字符替换,中间有一个空格。
答案3
并且还awk
设置FS
为[(_]
:
awk -v FS='[(_]' '{print $2,$6}' file
XXX DFG
GYZ TYU
UFG QWE
JTH YUT
即分隔符可以是正则表达式。这里有更多的例子: https://stackoverflow.com/questions/12204192/using-multiple-delimiters-in-awk
答案4
Ased
适用于任意数量的“字段”,但代价是每一端都有额外的空间
sed -E "s/[c_][^(]+./ /g" file
c
从或开始的全局搜索_
[c_]
后面跟着任何不是(
[^(]+
加上下一个字符.
(该字符将是(
一行中的最后一个字符),并将其替换为空格。
或者
这awk
也是“字段数量”不可知的
awk -F\( '{for (i=2; i<=$NF; i++) $(i-1)=substr($i,1,3); $NF=""}1' file
设置FS
为(
,然后从第二个到最后一个循环遍历字段,将字段设置i-1
为等于字段的前 3 个字符i
,并在打印前清除最后一个字符。