使用awk解析和修改每个CSV字段

时间:2013-12-29 02:26:31

标签: parsing awk field

我需要从CSV标题行解析和修改动态sqlite create table语句中的每个字段。以下是具有适当输出的命令行的作用:

echo ",header1,header2,header3"| awk 'BEGIN {FS=","}; {for(i=2;i<=NF;i++){printf ",%s text ", $i}; printf "\n"}' 
,header1 text ,header2 text ,header3 text

好吧,当它从bash shell脚本中运行时会中断。我通过将输出写入如下文件来实现它:

echo $optionalHeaders | awk 'BEGIN {FS=","}; {for(i=2;i<=NF;i++){printf ",%s text ", $i}; printf "\n"}' > optionalHeaders.txt

这很糟糕!有很多示例显示如何解析/修改特定的第N个字段。此问题需要修改每个字段。是否有一个更简洁和优雅的Awk one liner,可以将其内容存储到变量而不是写入文件?

4 个答案:

答案 0 :(得分:2)

sed通常是单行上简单替换的正确工具。请选择:

$ echo ",header1,header2,header3"  | sed 's/[^,][^,]*/& text/g'
,header1 text,header2 text,header3 text

$ echo ",header1,header2,header3"  | sed -r 's/[^,]+/& text/g'
,header1 text,header2 text,header3 text

上面的最后一个要求GNU sed使用ERE而不是BRE。如果您愿意,可以使用gsub()在awk中执行相同的操作:

$ echo ",header1,header2,header3"  | awk '{gsub(/[^,]+/,"& text")}1'
,header1 text,header2 text,header3 text

答案 1 :(得分:0)

我发现了问题而且是我...我忘了将变量的内容回显给Awk命令。 Brianadams的评论非常简单,迫使我重新查看我的代码并发现问题!谢谢!

我很乐意解决这个问题,但是如果有人想提出一个更简洁优雅的Awk one liner - 那就太酷了。

答案 2 :(得分:0)

您可以尝试以下操作:

#! /bin/bash

header=",header1,header2,header3"
newhead=$(awk 'BEGIN {FS=OFS=","}; {for(i=2;i<=NF;i++) $i=$i" text"}1' <<<"$header") 
echo "$newhead"

带输出:

,header1 text,header2 text,header3 text

答案 3 :(得分:0)

不是逐个修改字段,而是另一个选项是简单替换:

echo ",header1,header2,header3" | awk '{gsub(/[^,]+/, "& text", $0); print}'

也就是说,用附加的text替换一系列非逗号字符。

另一种选择是替换逗号,但是由于标题行的不规则性(第一个逗号必须单独留下,最后没有逗号),这样就不那么容易了:

echo ",header1,header2,header3" | awk '{gsub(/,/, " text,", $0); sub(/^ text,/, "", $0); print $0 " text"}'

顺便说一下,sed中两个命令的粗略等价物:

echo ",header1,header2,header3" | sed -e 's/[^,]\{1,\}/& text/g'
echo ",header1,header2,header3" | sed -e 's/\(.\),/\1 text,/g' -e 's/$/ text/'