鉴于此input_file:
1234 1234 abcd
1234 abcd
当我跑步时,awk无法识别空列:
awk '{print $1,$2}' input_file
我明白了:
1234 1234
1234 abcd
如何让awk给我:
1234 1234
1234
答案 0 :(得分:3)
awk
程序通常使用字段分隔符来确定哪些字符属于哪些字段。如果你的第二行只包含空格,则无法使用那个方法进行拆分。
然而,GNU awk
允许您设置一个更适合固定宽度数据的FIELDWIDTHS
变量,因为这似乎是您所拥有的:
pax> cat infile
1234 5678 abcd
1234 abcd
pax> awk 'BEGIN{FIELDWIDTHS="4 1 4"}{print "<"$1","$3">"}' infile
<1234,5678>
<1234, >
在这种情况下,它是字段1和 3 ,因为字段2是第一个和第二个真实列之间的空格:
1234 5678 abcd
\__/|\__/|\__/
1 2 3 4 5
我通常这样做,因为我不希望空间成为数据的一部分(如果我想在输出中输出不同的字符),但是,如果你是无论如何转移空间,你也可以使用更简单的方法:
pax> awk 'BEGIN{FIELDWIDTHS="5 4"}{print "<"$1$2">"}' infile
<1234 5678>
<1234 >
在这种情况下,字段1是五个字符1234<space>
。
如果要进行固定宽度处理,但 能够轻松适应以后的宽度更改,则可以修改awk
脚本,以便从文件本身获取该信息。
不是来自实际数据行,因为字段可能有空格,但您可以添加标题行以完全指定要使用的宽度(确保标题行当然不被视为数据)。
以下脚本显示了这一点(awk
脚本现在位于文件中,因为它变得复杂了):
pax> cat infile
#### ###### ####
1234 567890 abcd
1234 abcd
pax> cat awkfile.awk
NR == 1 {
# Header: construct field widths string
# "a 1 b 1 c 1 d ... z"
# where a..z are lengths of fields.
FIELDWIDTHS = length($1)
for (i = 2; i < NF; i++) {
FIELDWIDTHS = FIELDWIDTHS" 1 "length($i)
}
next
}
{
# Then use that FIELDWIDTHS string for
# all other records.
print "<"$1","$3">"
}
pax> awk -f awkfile.awk infile
<1234,567890>
<1234, >
您会发现可以根据需要更改字段长度,如果标题行正确,它将适应。
答案 1 :(得分:1)
有字段分隔符==字段是一种不可能的。 您需要考虑输入数据的操作。
以下是固定宽度字段的一些示例:
$ awk '{gsub(" [[:space:]]{4} "," ---- ");print}' file1
1234 1234 abcd
1234 ---- abcd
您可以随时恢复:
$ awk '{gsub(" [[:space:]]{4} "," ---- ");print}' file1 |awk '{gsub("----"," ");print}'
1234 1234 abcd
1234 abcd
对于非固定宽度的情况,您可以使用类似下面的内容,这将在其他内容中转换两个以上空格的序列:
$ awk '{gsub(" [[:space:]]{2,} "," - ");print}' file
1234 1234 abcd
1234 - abcd
答案 2 :(得分:1)
我认为最简单的方法是将字段分隔符声明为“\t”(假设它确实是制表符分隔的)。
awk -F'\t' '{print $1,$2}' file_name
您的代码现在应该可以正常工作了。
答案 3 :(得分:0)
如果您的实际Input_file与显示的示例相同,那么以下内容也可以帮助您。
awk '{sub(/ +[a-zA-Z]+/,"")} 1' Input_file