AWK:打印$ i什么都不返回

时间:2012-10-09 00:26:13

标签: bash printing awk

$file是一个csv(制表符分隔),有59列和64行。第1列始终是一个字符串,cols 2+总是一个整数(当值为NULL时除外)。

cat ${file} | while read line 
    do awk -F'\t' '{ for (i=2; i<=NF; i++) print $1 "\t" $i "." }';
    done;

输出:

Excellent   .
Good    .
…

然而将$i切换为$2仍有效:

Excellent   29.
Good    7.
…

为什么?

修改

#lines 1 & 2 from data.csv (columns truncated for brevity):
Excellent   29  54  47  46  38  22  50
Good    7   14  27  24  26  36  20

#reform.sh
file=$1;
awk -F'\t' '{ for (i=2; i<=NF; i++) print $1 "\t" $i; }' ${file};

仍然像以前一样表现/返回。

解决

批准的答案确实提供了AWK的正确输出。重新启动终端应用程序后,脚本按照描述执行。我无法确定终端应用程序问题的原因。

2 个答案:

答案 0 :(得分:7)

我觉得你错了。你拥有的脚本没有输出任何智能的(a),因为当你试图将每一行读入$line时,你实际上并没有将它们提供给{{ 1}}。

你可以用以下内容摆脱多余的(和不正确的)循环:

awk

如以下成绩单所示:

awk -F'\t' '{ for (i=2; i<=NF; i++) print $1 "\t" $i "." }' ${file}

正如您所看到的(虽然我使用的是空格而非标签),但这可以为您提供所需的输出。


为了回应你断言不能正常工作,我恐怕不得不乞求不同。以下脚本(带标签)显示它的效果与宣传的一样。

pax> echo 'A 1 2
...> B 3 4
...> C 5 6' >qq.in

pax> cat qq.in
A 1 2
B 3 4
C 5 6

pax> awk -F' ' '{ for (i=2; i<=NF; i++) print $1 " " $i "." }' qq.in
A 1.
A 2.
B 3.
B 4.
C 5.
C 6.

如果它实际上并不适用于您的环境,那就是另一个问题。您可能会遇到错误pax> cat qq.in Excellent 29 54 47 46 38 22 50 Good 7 14 27 24 26 36 20 pax> awk -F'\t' '{ for (i=2; i<=NF; i++) print $1 "\t" $i; }' qq.in Excellent 29 Excellent 54 Excellent 47 Excellent 46 Excellent 38 Excellent 22 Excellent 50 Good 7 Good 14 Good 27 Good 24 Good 26 Good 36 Good 20 或其他任何原因导致失败。

首先,找出您正在使用的awk版本和操作系统,例如:

awk

(a):它确实会输出的东西,但几乎肯定不是你所期望的。让我们看看现实中发生的事情。请考虑以下与您的原文相似的成绩单:

awk --version
uname -a

现在看起来很奇怪,它似乎丢掉了第一行。

原因是pax> ( echo 1; echo 2; echo 3 ) | while read line ; do ...> awk '{print "[" $0 "]"}' ...> done [2] [3] while之间的脱节。 awk从标准输入读取第一行并将其分配给while,然后执行$line部分的正文。

该主体是do..done,没有输入文件,因此从标准输入获取输入!

这意味着它将“吸收”其余的标准输入流并进行处理。

然后,它将返回awk循环但是,如果标准输入没有更多数据,它将完成。它可能更好地说明:

while

如果您实际连接 pax> ( echo 1; echo 2; echo 3 ) | while read line ; do ...> echo "read: $line" ...> awk '{print "awk: " $0}' ...> done read: 1 awk: 2 awk: 3 while以及awk部分,您会看到它正常运行:

echo "$line" |

当然,在pax> ( echo 1; echo 2; echo 3 ) | while read line ; do ...> echo "$line" | awk '{print "[" $0 "]"}' ...> done [1] [2] [3] 完全能够一次一个地处理多个行时,将输入分成行并将它们一次发送到awk是没有意义的。自己的。

因此,在这个答案的第一个代码块中显示的单行awk命令仍然是更好的方法。

答案 1 :(得分:2)

你可以做到

awk -F$'\t' '{ for (i=2; i<=NF; i++) print $1 "\t" $i "." }' FILE

而不是所有不需要的管道。