awk脚本读取txt文件

时间:2016-01-09 20:29:57

标签: csv awk

如何使用awk创建以下输出?我无法为逗号分隔数据创建循环。

awk '{print "echo "$1"\nadd "$2"\nremove "$3"\nlist "$4}' test.txt

的test.txt

1 abc,bcd xyz,yza qwe,wer
2 abc xyz qwe
3 abc xyz,yza qwe,wer
4 abc,bcd xyz wer

输出:

echo 1
add abc
add bcd
remove xyz
remove yza
list qwe
list wer
echo 2
add abc
remove xyz
list qwe
echo 3
add abc
remove xyz
remove yza
list qwe
list wer
echo 4
add abc
add bcd
remove xyz
list wer

6 个答案:

答案 0 :(得分:2)

当我必须自己进行拆分并遍历生成的数组时,我总觉得awk失去了一点pizazz,但这是一种直接的方式,使用函数添加第二个循环以处理你的空间 - 分隔的字段(它们本身是以逗号分隔的值):

$ cat test.awk
function print_all(label, values) {
    split(values, v, ",")
    for (i=1; i<=length(v); ++i) {
        print label " " v[i]
    }
}

{
    print "echo " $1
    print_all("add", $2)
    print_all("remove", $3)
    print_all("list", $4)
}

$ cat test.txt
1 abc,bcd xyz,yza qwe,wer
2 abc xyz qwe
3 abc xyz,yza qwe,wer
4 abc,bcd xyz wer

$ awk -f test.awk test.txt
echo 1
add abc
add bcd
remove xyz
remove yza
list qwe
list wer
echo 2
add abc
remove xyz
list qwe
echo 3
add abc
remove xyz
remove yza
list qwe
list wer
echo 4
add abc
add bcd
remove xyz
list wer

答案 1 :(得分:0)

你有两个循环,这就是你遇到问题的原因 - 你需要在空格上拆分你的行,然后用逗号分割你的子元素。

我建议使用perl

#!/usr/bin/env perl
use strict;
use warnings;

my @actions = qw ( echo add remove list ); 

#iterate the lines    
while ( <DATA> ) {
   #split on whitespace
   my @fields = split; 
   #iterate actions and fields
   foreach my $action ( @actions ) { 
      #split each field on ,
      #print action and field for each. 
      print "$action $_\n" for split ( ",", shift @fields ); 
   }
}

__DATA__
1 abc,bcd xyz,yza qwe,wer
2 abc xyz qwe
3 abc xyz,yza qwe,wer
4 abc,bcd xyz wer

这给了我们:

echo 1
add abc
add bcd
remove xyz
remove yza
list qwe
list wer
echo 2
add abc
remove xyz
list qwe
echo 3
add abc
remove xyz
remove yza
list qwe
list wer
echo 4
add abc
add bcd
remove xyz
list wer

我认为你想要的是什么?

这可以减少到一个班轮:

perl -ane 'for my $act ( qw ( echo add remove list ) ) { print "$act $_\n" for split ",", shift @F }' test.txt

答案 2 :(得分:0)

不一定推荐,但如果你正在寻找契约,你可以用包括换行符在内的额外文本替换逗号。

a = "," $2; b = "," $3; c = "," $4;
gsub(/,/, "\nadd ", a);
gsub(/,/, "\nremove ", b);
gsub(/,/, "\nlist ", c);
print "echo " $1 a b c "\n"

答案 3 :(得分:0)

另一种替代方法是两阶段awk

$ awk '{ print "echo " $1; print "add " $2; print "remove " $3}' file 
  | awk -F'[ ,]' 'NF==3{print $1,$2; print $1,$3;next}1' 

答案 4 :(得分:0)

$ cat tst.awk
BEGIN { split("echo add remove list",names) }
{
    for (fldNr=1;fldNr<=NF;fldNr++) {
        split($fldNr,subFlds,/,/)
        for (subFldNr=1;subFldNr in subFlds; subFldNr++) {
            print names[fldNr], subFlds[subFldNr]
        }
    }
}

$ awk -f tst.awk file
echo 1
add abc
add bcd
remove xyz
remove yza
list qwe
list wer
echo 2
add abc
remove xyz
list qwe
echo 3
add abc
remove xyz
remove yza
list qwe
list wer
echo 4
add abc
add bcd
remove xyz
list wer

答案 5 :(得分:0)

awk -F" " '{for(i=1;i<=NF;i++){a[i]=$i;} {print "echo "a[1]"\n""add "a[2]"\nremove "a[3]"\nlist "a[4];}}' filename | awk -F" " '{sub(/,/,"\n"$1" ",$0);print}'

可以使用上面的代码。 另外,我想获得其他人的输入,以获得上述版本的优化代码片段。