2010-09-13 144 views
1

我有一个看起来像这样的文件:如何使用AWK打印?

1 543423 34354 
2 5654656 3423 xyz_1378,xyz_1379 
3 4645656 34234354 xyz_1384,xyz_1385 
4 5654 78678 xyz_1390,xyz_1391,xyz_1392 
5 54654 76867 xyz_1411,xyz_1412,xyz_1413 
6 54654 8678 
7 56546 67867 xyz_1711 
8 678 7867 
9 76867 7876 xyz_2940 
10 6786 678678 xyz_3101,xyz_3102,xyz_3103,xyz_3104,xyz_3105,xyz_3106,xyz_3107 
11 67867 78678 

注意它包含4个字段,空格隔开。最后一个(第四个)字段可能为空,并且可能包含以逗号分隔的多个值。

我想打印最后一行的所有值,每行一个。我该怎么做(最好使用awk)?

更新: 我需要批量处理许多文件(获取所有文件的连接输出)。

这工作:

for x in *; do awk '{print $4}' $x/filename | awk --field-separator="," '{if ($0 != "") {for (i=1; i<NF+1; i++) print $i}}'; done; 

,并返回类似

xyz_1378 
xyz_1221 
xyz_97 
xyz_132523 
xyz_242 

我现在唯一缺少的,就是我希望上述各行开始与一个额外的字段 - $ x(for循环中的一个)。

我试着改变print $iprint $x,$i" but在这个范围内x似乎没有被正确识别。有任何想法吗?

谢谢!

+0

当你说“我想打印最后一行的所有值,每行一个。”你的意思是“最后一列”? – 2010-09-13 19:37:32

+0

@是,对不起:) – 2010-09-14 08:09:45

回答

2

使用awk的-v管道过滤输出选项将变量传递给awk脚本,而不是依赖shell的替换。此外,您只需要一个电话给awk的

for dir in *; do 
    awk -v "dir=$dir" ' 
     NF==4 { 
      n = split($4, a, ",") 
      for (i=1; i<=n; i++) {print dir "\t" a[i]} 
     } 
    ' "$dir/filename" 
done 

,或者,如果你不介意看到“目录/文件名”:

awk ' 
    NF==4 { 
     n = split($4, a, ",") 
     for (i=1; i<=n; i++) {print FILENAME "\t" a[i]} 
    } 
' */filename 

如果你有目录的庞大的数字,你的shell会阻塞扩大 “* /文件名” 的时候,所以使用查找和xargs的:

find . -type f -name filename -print0 | xargs -0 awk '...' 

(需要GNU查找/为-print0 xargs的/ -0选项)

+1

小评论:而不是'for(i = 1; i <= n; i ++)'更简单'for(i in a) '可以使用,如果顺序不重要。 – TrueY 2013-04-22 12:58:43

-1

使用NF>=4作为条件以查看该领域是否有任何东西。然后split($4,a,/,/)会给你一个数组a与所有值。它放入一个大的结果数组:

NF>=4 { 
    n = split($4, a, /,/); 
    for(i=1; i<=n; i++) { 
     result[a[i]] = 0; 
    } 
} 

,并在最后打印:

END { 
    for(val in result) { 
     print val; 
    } 
} 

如果你想要的排序,通过sort(1)

+0

我尝试过测试,但是这打印1到7,每个都在一条线上。我在某个地方犯了什么错误? – 2010-09-13 14:09:35

+0

-1:这似乎是打印最后一行数值的最后几位数字,巧合的是,从1到7. – 2010-09-13 15:37:12

+0

对不起,我忘记了'for(x in y)'不适用于数组。固定。 – 2010-09-14 07:04:46

0

也许你可以改变你的命令语句之一

awk '{print FILENAME "," $4}' $x 

,然后在这个输出工作。

FILENAME是内部awk变量,用于获取它正在处理的文件的文件名。