试图用另一种模式替换一种模式
Trying to replace a pattern with another one
这是我在这个网站上的第一个问题。(很高兴我发现了这个社区)
我正在尝试替换文件(多行)中看起来像这样的特定模式:
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(/.*<<</,"", ); }1' }'
然后用 sed 解析输出(从两个字符串中删除 ) 和 ( 字符。但它没有用。
感谢阅读。
Perl 的正则表达式有一个 "non-greedy" awk 没有的匹配特性:
perl -pe '
s/ \| # the first delimiter
(.*?) # capture up to ...
>>> # the middle delimiter
(.*?) # capture up to ...
\| # the last delimiter
/( | )/gx
' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
看起来这只是每行中的一个简单替换,所以您只需要 sed:
$ sed 's/| *\([^|]*\) >>> \([^|]*\) *|/( | )/g' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
您可以在 GNU awk 中使用 gensub() 或使用 match() 和 substr() 的其他 awk 执行相同的操作。
在 sed 中使用扩展正则表达式:
sed -r 's/\|([^|]+)[[:space:]]*>>>[[:space:]]*([^|]+)\|/( | )/g' File
逻辑:
我们寻找以 |
开头的模式,然后是一系列非 |
字符,然后是 >>>
,然后是一系列非 |
字符再次。查看使用 (
和 )
完成的分组。然后我们根据需要替换这些模式。 ( | )
是替换模式,其中 \1 和 \2 分别是第一组和第二组。
使用 sed 中的基本正则表达式:
sed 's/|\([^|]*\)[[:space:]]*>>>[[:space:]]*\([^|]*\)|/( | )/g' File
让我们试试 awk:
awk 'NR%2{ printf("%s", [=10=]) } NR%2==0{ printf("( %s %s",$NF,RS); gsub(/>>>.*$/,")"); printf("%s",[=10=]) }' RS='|' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
RS
定义|
为记录分隔符。因此,当输入记录编号 (NR) 不是 2 的模数 (NR%2
return 1) 时,则打印该记录本身。如果 NR
是 2 的模块(NR%2==0
表示如果记录是 2 的模块),则打印单个左括号,然后打印最后一个字段并打印记录分隔符(printf("( %s %s",$NF,RS)
) , 然后用右括号替换 >>>.*$
并打印记录的其余部分 (gsub(/>>>.*$/,")"); printf("%s",[=18=])
)
这是我在这个网站上的第一个问题。(很高兴我发现了这个社区)
我正在尝试替换文件(多行)中看起来像这样的特定模式:
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(/.*<<</,"", ); }1' }'
然后用 sed 解析输出(从两个字符串中删除 ) 和 ( 字符。但它没有用。
感谢阅读。
Perl 的正则表达式有一个 "non-greedy" awk 没有的匹配特性:
perl -pe '
s/ \| # the first delimiter
(.*?) # capture up to ...
>>> # the middle delimiter
(.*?) # capture up to ...
\| # the last delimiter
/( | )/gx
' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
看起来这只是每行中的一个简单替换,所以您只需要 sed:
$ sed 's/| *\([^|]*\) >>> \([^|]*\) *|/( | )/g' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
您可以在 GNU awk 中使用 gensub() 或使用 match() 和 substr() 的其他 awk 执行相同的操作。
在 sed 中使用扩展正则表达式:
sed -r 's/\|([^|]+)[[:space:]]*>>>[[:space:]]*([^|]+)\|/( | )/g' File
逻辑:
我们寻找以 |
开头的模式,然后是一系列非 |
字符,然后是 >>>
,然后是一系列非 |
字符再次。查看使用 (
和 )
完成的分组。然后我们根据需要替换这些模式。 ( | )
是替换模式,其中 \1 和 \2 分别是第一组和第二组。
使用 sed 中的基本正则表达式:
sed 's/|\([^|]*\)[[:space:]]*>>>[[:space:]]*\([^|]*\)|/( | )/g' File
让我们试试 awk:
awk 'NR%2{ printf("%s", [=10=]) } NR%2==0{ printf("( %s %s",$NF,RS); gsub(/>>>.*$/,")"); printf("%s",[=10=]) }' RS='|' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )
RS
定义|
为记录分隔符。因此,当输入记录编号 (NR) 不是 2 的模数 (NR%2
return 1) 时,则打印该记录本身。如果 NR
是 2 的模块(NR%2==0
表示如果记录是 2 的模块),则打印单个左括号,然后打印最后一个字段并打印记录分隔符(printf("( %s %s",$NF,RS)
) , 然后用右括号替换 >>>.*$
并打印记录的其余部分 (gsub(/>>>.*$/,")"); printf("%s",[=18=])
)