这是我在这个网站上的第一个问题。(很高兴我发现了这个社区)
我正在尝试替换文件中的特定模式(多行)看起来像这样:
Bla bla bla bla |SMTH AWESOME INSIDE >>> LOL| bla bla bla | let's do it again >>> AWESOME |
进入看起来像这样的格式
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
我尝试使用一个逐字解析行的代码,如果找到" |"字符开始创建包含第一个单词的字符串,然后在找到>>>之后字符它开始创建第二个字符串,直到找到" |"最后一个角色,但它没有用。
之后我也尝试使用AWK(但由于我是linux新手,我也失败了。
awk -F 'BEGIN { FS=OFS="|" } { sub(/.*<<</,"", $2); }1' $1 }'
然后用sed解析输出(删除)和(两个字符串中的字符。但它没有工作。
感谢您的阅读。
答案 0 :(得分:2)
看起来这只是每行中的一个简单替换,所以你需要的只是sed:
$ sed 's/| *\([^|]*\) >>> \([^|]*\) *|/( \2 | \1 )/g' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
您可以在GNU awk中使用gensub()或其他具有match()和substr()的awks执行相同的操作。
答案 1 :(得分:1)
Perl的正则表达式具有“非贪婪”匹配功能,而awk则没有:
perl -pe '
s/ \| # the first delimiter
(.*?) # capture up to ...
>>> # the middle delimiter
(.*?) # capture up to ...
\| # the last delimiter
/($2 | $1)/gx
' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
答案 2 :(得分:1)
在 sed 中使用扩展的正则表达式:
sed -r 's/\|([^|]+)[[:space:]]*>>>[[:space:]]*([^|]+)\|/( \2 | \1 )/g' File
<强>逻辑:强>
我们会寻找一种模式,该模式以|
开头,后跟一系列非|
字符,后跟>>>
,后跟一系列非|
字符。查看使用(
和)
完成的分组。然后我们根据需要替换这些模式。 ( \2 | \1 )
是替换模式,其中\ 1和\ 2分别是第一个和第二个分组。
使用 sed 中的基本正则表达式:
sed 's/|\([^|]*\)[[:space:]]*>>>[[:space:]]*\([^|]*\)|/( \2 | \1 )/g' File
答案 3 :(得分:0)
让我们试试awk:
awk 'NR%2{ printf("%s", $0) } NR%2==0{ printf("( %s %s",$NF,RS); gsub(/>>>.*$/,")"); printf("%s",$0) }' RS='|' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
RS
将|
定义为记录分隔符。因此,当输入记录号(NR)不是2的模块(NR%2
返回1)时,则打印该记录本身。如果NR
是2的模块(NR%2==0
表示如果记录是2的模块),则打印一个打开的括号,然后从中打印最后一个字段并打印记录分隔符(printf("( %s %s",$NF,RS)
) ,然后用小括号替换>>>.*$
并打印剩下的记录(gsub(/>>>.*$/,")"); printf("%s",$0)
)