Csv 读取txt文件的awk脚本
如何使用awk创建以下输出?我无法为逗号分隔的数据创建循环Csv 读取txt文件的awk脚本,csv,awk,Csv,Awk,如何使用awk创建以下输出?我无法为逗号分隔的数据创建循环 awk'{print“echo”$1”\nadd“$2”\n删除“$3”\n列出“$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 ad
awk'{print“echo”$1”\nadd“$2”\n删除“$3”\n列出“$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
你有两个循环,这就是为什么你有一个问题-你需要在空格上拆分行,但在逗号上拆分子元素 我建议使用
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
我想这就是你想要的
这可以简化为一个衬里:
perl -ane 'for my $act ( qw ( echo add remove list ) ) { print "$act $_\n" for split ",", shift @F }' test.txt
当我必须对生成的数组进行拆分和循环时,我总是觉得awk失去了一点活力,但这里有一个简单的方法,使用函数添加第二个循环,以便处理空格分隔的字段(它们本身是逗号分隔的值):
$cat test.awk
函数打印全部(标签、值){
拆分(值,v,“,”)
对于(i=1;i不一定推荐,但如果您正在寻找紧凑型,您可以用额外的文本(包括换行符)替换逗号
a = "," $2; b = "," $3; c = "," $4;
gsub(/,/, "\nadd ", a);
gsub(/,/, "\nremove ", b);
gsub(/,/, "\nlist ", c);
print "echo " $1 a b c "\n"
另一种替代方法是两阶段awk
$ awk '{ print "echo " $1; print "add " $2; print "remove " $3}' file
| awk -F'[ ,]' 'NF==3{print $1,$2; print $1,$3;next}1'
$cat tst.awk
开始{split(“echo add remove list”,name)}
{
对于(fldNr=1;fldNrawk-F“””{for(i=1;iThanks-karakfa。您能解释一下第二个awk语句吗?它适用于示例输入,但我正在尝试修改我的原始输入。好吧,它假设您将有1或2个子字段。第二个awk按空格和逗号拆分字段。对于2个子字段,NF将为3,将其余字段拆分为两行。这将适用于e示例集,但对于更多的子字段可能更难扩展。如果这是您的输入,循环解决方案可能会更好。我的输入文件中有一行:“abc bcd cde def:fed fed:abc,bcd”我需要将fed:abc,bcd拆分为两行,如:“abc bcd cde def:fed fed:abc”“abc bcd cde def:fed fed:bcd”该死,我对这个问题投了更高的票,因为它似乎写得很好,有简明的样本输入、输出和解决问题的尝试,现在OP的评论显示了一个问题中完全没有的主要要求:-(!我有不止一个解决方案,但我喜欢@karakfa的方法,一行awk脚本。这也有效,但我意识到我有“:”。我将提出一个新问题。感谢大家的支持。
a = "," $2; b = "," $3; c = "," $4;
gsub(/,/, "\nadd ", a);
gsub(/,/, "\nremove ", b);
gsub(/,/, "\nlist ", c);
print "echo " $1 a b c "\n"
$ awk '{ print "echo " $1; print "add " $2; print "remove " $3}' file
| awk -F'[ ,]' 'NF==3{print $1,$2; print $1,$3;next}1'
$ 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
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}'