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

jac*_*cob 2 printing bash awk

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

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

输出:

Excellent   .
Good    .
…
Run Code Online (Sandbox Code Playgroud)

然而切换$i$2工作:

Excellent   29.
Good    7.
…
Run Code Online (Sandbox Code Playgroud)

为什么??

编辑:

#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};
Run Code Online (Sandbox Code Playgroud)

仍然像以前一样表现/回归.

决议:

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

pax*_*blo 7

我觉得你错了.你拥有它的脚本不输出任何智能(a)因为,当你试图读取每一行时$line,你实际上并没有给它们awk.

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

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

如以下成绩单所示:

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.
Run Code Online (Sandbox Code Playgroud)

正如您所看到的(虽然我使用的是空格而不是制表符),但这可以为您提供所需的输出.


为了回应你断言它仍然不起作用,我恐怕不得不乞求不同.以下脚本(带标签)显示它的工作方式与宣传的一样.

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
Run Code Online (Sandbox Code Playgroud)

如果它实际上并不适用于您的环境,那就是另一个问题.您可能有一个错误awk或任何其他原因导致失败.

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

awk --version
uname -a
Run Code Online (Sandbox Code Playgroud)

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

pax> ( echo 1; echo 2; echo 3 ) | while read line ; do
...>     awk '{print "[" $0 "]"}'
...> done
[2]
[3]
Run Code Online (Sandbox Code Playgroud)

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

原因是它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
Run Code Online (Sandbox Code Playgroud)

如果您实际连接while以及下面awkecho "$line" |部分,您将看到它正常工作:

pax> ( echo 1; echo 2; echo 3 ) | while read line ; do
...>     echo "$line" | awk '{print "[" $0 "]"}'
...> done
[1]
[2]
[3]
Run Code Online (Sandbox Code Playgroud)

当然,将输入划分为行并将它们awk一次发送到一行是没有意义的,因为awk它完全能够一次一个地处理多行.

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