我认为你错了。您拥有的脚本不会输出任何智能(a),因为当您尝试将每一行读入$line
时,您实际上并没有将它们提供给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
您使用的是什么版本和操作系统,例如:
awk --version
uname -a
(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
它完全能够一次处理多行。
所以这个答案的第一个代码块中显示的单行awk
命令仍然是一种更好的方法。