![](/img/trans.png)
[英]Ignoring commas within fields using AWK when there are multiple field separators
[英]Custom field separators in awk with regex: problem with leading spaces and commas
我在 stackoverflow 上四处寻找解决方案,我找到了一些相关的答案,但我一直无法找到明确的解决方案来解决我的疑问。 我希望我不会问重复的问题。
让我们考虑一个文件
cat > file << EOF
1 2 3 4, 5,, 6, 7
EOF
我想使用任意数量的逗号和空格作为分隔符。 使用 awk,用 F"[ ,]*" 设置字段分隔符,我得到了想要的结果,即:
awk -F"[ ,]+" '{print $1}' file --> 1
awk -F"[ ,]+" '{print $2}' file --> 2
awk -F"[ ,]+" '{print $3}' file --> 3
awk -F"[ ,]+" '{print $4}' file --> 4
awk -F"[ ,]+" '{print $5}' file --> 5
awk -F"[ ,]+" '{print $6}' file --> 6
awk -F"[ ,]+" '{print $7}' file --> 7
但是,如果我有前导空格,我就会遇到问题。 例如:
有一个领先的空间
cat > file << EOF
1 2 3 4, 5,, 6, 7
EOF
我得到
awk -F"[ ,]+" '{print $1}' file -->
awk -F"[ ,]+" '{print $2}' file --> 1
awk -F"[ ,]+" '{print $3}' file --> 2
...
两个前导空格相同
cat > file << EOF
1 2 3 4, 5,, 6, 7
EOF
awk -F"[ ,]+" '{print $1}' file -->
awk -F"[ ,]+" '{print $2}' file --> 1
awk -F"[ ,]+" '{print $3}' file --> 2
...
等等。
然而,问题不仅在于空间。 例如与
cat > file << EOF
1,2,3,
EOF
我有
awk -F"," '{print $1}' file --> 1
awk -F"," '{print $2}' file --> 2
awk -F"," '{print $3}' file --> 3
awk -F"," '{print $4}' file -->
这是我所期望的,但与
cat > file << EOF
,1,2,3
EOF
我得到
awk -F"," '{print $1}' file -->
awk -F"," '{print $2}' file --> 1
awk -F"," '{print $3}' file --> 2
awk -F"," '{print $4}' file --> 3
我不明白为什么。
awk 似乎以不同的方式处理前导分隔符。 可能,我误解了正则表达式语法。 事实上,我不明白为什么设置 -F"" 前导空格会以正确的方式处理,而设置 -F"[ ]*" 我有同样的问题。
总之,这些是我的问题:为什么我会获得前导空格或前导逗号的这些结果,以及要考虑的正确语法是什么,作为字段分隔符,任意数量的逗号和空格,无论它们是否前导。
是的,有一些不一致,我想是为了方便。
默认分隔符忽略前导/尾随空格
$ echo " 1 2 " | awk '{for(i=1;i<=NF;i++) print i"--> "$i}'
1--> 1
2--> 2
将FS
设置为 space 的行为相同
$ echo " 1 2 " | awk -F' ' '{for(i=1;i<=NF;i++) print i"--> "$i}'
1--> 1
2--> 2
但是,字符集。
$ echo " 1 2 " | awk -F'[ ]' '{for(i=1;i<=NF;i++) print i"--> "$i}'
1-->
2--> 1
3--> 2
4-->
因为有 3 个分隔符(所以假设有四个字段)。 使用逗号分隔符,您将不会获得默认行为,而只会获得最后一个版本。
如果你想模仿逗号和空格的默认行为,你需要编写自己的处理方式,像这样
$ echo " ,1 2," |
awk -F'[ ,]+' 'NF{if($1=="") {for(i=2;i<=NF;i++) $(i-1)=$i; NF--}
if($NF=="") NF--}
{for(i=1;i<=NF;i++) print i"--> "$i}'
1--> 1
2--> 2
说明:如果第一个字段为空,则将所有字段左移一位,字段数减一; 同样,如果最后一个字段为空,只需减少字段数。 最后一条语句用于按字段位置编号一行打印字段。
在尝试修复字段之前,更新以处理空行添加保护NF
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.