![如果找到 4 位数字,则在 csv 中打印数字和下一行值](https://linux22.com/image/167423/%E5%A6%82%E6%9E%9C%E6%89%BE%E5%88%B0%204%20%E4%BD%8D%E6%95%B0%E5%AD%97%EF%BC%8C%E5%88%99%E5%9C%A8%20csv%20%E4%B8%AD%E6%89%93%E5%8D%B0%E6%95%B0%E5%AD%97%E5%92%8C%E4%B8%8B%E4%B8%80%E8%A1%8C%E5%80%BC.png)
我有 csv 格式的数据:
125867569,98652343,7012,879456217,20121221,7065,758964231,856421345
我想要的输出:
7012,879456217,7065,758964231
我怎样才能做到这一点?
答案1
类似的东西可以完成这项工作:
awk -F, '{for (i=1;i<NF-1;i++) if (length($i)==4 && int($i)==$i) printf("%s,%s,", $i,$(i+1))}' input_file
如果您想要“绝对矫枉过正”的版本,它可以删除不必要的内容,
并在输出中添加换行符,请尝试
awk -F, '{if (g) printf("\n"); f=0; for (i=1;i<NF-1;i++) if (length($i)==4 && int($i)==$i) {if (f) printf(","); else f=1; printf("%s,%s", $i,$(i+1)); g=1}} END{if (g) printf("\n")}' input_file
答案2
如果您的文件从不包含引号或换行符,您可以使用cut
:
cut -d, -f3,4,6,7 file.csv
-d
指定分隔符-f
指定要输出的列
答案3
ruby -rcsv -e '
CSV.foreach(ARGV.shift) do |row|
puts row.each_cons(2)
.select {|pair| pair.first =~ /^\d{4}$/}
.flatten
.to_csv
end
' file.csv
答案4
您可以通过多种方式进行:
方法 1:GNU sed(启用扩展正则表达式)
解释:首先在模式空间的开头放置一个标记。查看右侧的两个字段,如果我们在右侧看到一个 4 位数字,则使标记向右跳两个字段。 OTW,使标记跳一位字段并从模式空间中删除该字段。当标记到达模式空间的末尾时,此过程停止。此时模式空间中剩下的内容就是答案。
$ sed -re '
s/^/\n/
:a;/\n$/!{
s/\n([0-9]{4},[^,]+(,|$))/\1\n/;ta
s/\n[^,]+(,|$)/\n/;ta
}
s/,?\n$//;/./!d
' file.csv
$ perl -F, -lane '$,=",";
print /(?:^|,)(\d{4},[^,]+)/g;
' file.csv
$ perl -F, -lane '$,=",";
shift(@F) =~ /^(\d{4})$/
and push(@A, $1, shift(@F))
while @F > 1;
print splice @A if @A;
' file.csv
$ awk -F, -vOFS=, '{
N = split($0, a, FS)
$0 = ""
for ( i=j=1; i<N; )
if ( a[i] ~ /^[0-9]{4}$/ )
for ( k=0; k<2; k++ )
$(j++) = a[i++]
else
++i
}NF' file.csv