我需要从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,可以将其内容存储到变量而不是写入文件?
答案 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/'