我有一个带有输入文本的文件(这不是原始文件,只是输入文本的示例),我想将所有2个字母的字符串替换为数字100。在这个文件中FS可以是:,|或" " (空格),我别无选择,只能将它们全部三个都视为FS,我想在输出中的原始位置(如输入文件中)保留这些字段分隔符
A:B C|D
AA:C EE G
BB|FF XX1 H
DD:MM:YY K
我试过了
awk -F"[:| ]" '{gsub(/[A-Z]{2}/,"100");print}'
但这似乎不起作用,请建议。
期望的输出:
A:B C|D
100:C 1000 G
100|100 1001 H
100:100:100 K
答案 0 :(得分:3)
POSIX awk中没有保留与RS(POSIX)定义的字符串或FS定义的regexp匹配的字符串的功能。因为POSIX RS只是一个字符串,所以不需要这样的功能,并且对于每个FS匹配字符串来说这样做是不必要的低效,因为它很少需要。
使用GNU awk,其中RS可以是正则表达式,而不仅仅是字符串,您可以保留与正则表达式RS匹配的字符串,但是没有功能可以保留与FS匹配的值,这与POSIX没有相同的效率原因相同。 #39;做到了。相反,在GNU awk中,他们在split()中添加了第4个arg,因此如果需要,可以自己保留数组中与FS匹配的字符串(seps[]
以下):
$ awk -v FS='[:| ]' '{
split($0,flds,FS,seps)
gsub(/[A-Z]{2}/,"100")
for (i=1;i<=NF;i++) {
printf "%s%s", $i, seps[i]
}
print ""
}' file
A:B C|D
100:C 100 G
100|100 1001 H
100:100:100 K
在the GNU awk manual中查找split()
以获取更多信息。
答案 1 :(得分:1)
在这种情况下
sed 's/[A-Z]\{2\}/100/g' YourFile
awk '{gsub(/[A-Z]{2}/, "100"); print}' YourFile
在这种情况下不需要字段分隔,将所有大写字母组都改为“100”,除非你在OP中指定其他约束(就像字符串中的其他元素一样,你需要指定什么是可能的,理想的,添加预期结果的样本为univoq)
现在你肯定还有更多的东西,所以这个代码肯定会失败,因为ABC:DEF
改为100C:100F
,这肯定不是预期的
在这种情况下
awk -F '[[:blank:]:|]+' '
{
split( $0, aS, /[^[:blank:]:|]+/)
for( i=1;i<=NF;i++){
if( $i ~ /^[A-Z][A-Z]$/) $i = "100"
printf( "%s%s", $i, aS[i+1])
}
printf( "\n" )
} ' YourFile
答案 2 :(得分:0)
试试这个sed one-liner:
kent$ sed -r 's/(^|[:| ])[A-Z][A-Z]([:| ]|$)/\1100\2/g' file
A:B C|D
100:C 100 G
100|FF XX1 H
100:MM:100 K
注意:
这将搜索并替换模式:两个分隔符之间的两个[A-Z] 。如果这不是您想要的,请粘贴所需的输出。
答案 3 :(得分:0)
你的代码似乎与我的Gnu awk一样好用:
A:B C|D
100:C 100 G # even the typo in this record got fixed.
100|100 1001 H
100:100:100 K
我想问题是正则表达式/[A-Z]{2}/
应该写成/[A-Z][A-Z]/
。