如何使用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
答案 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}'
可以使用上面的代码。 另外,我想获得其他人的输入,以获得上述版本的优化代码片段。