使用 awk 在每个 header 列前加上字符串前缀

prefix every header column with string using awk

我有一堆大的 csv,我想在每个 header 列前加上固定字符串。每个文件都有500多列。

假设我的 header 是:

number;date;customer;key;amount

我试过这条 awk 行:

awk -F';' 'NR==1{gsub(/[^a-z_]/,"input_file.")} { print }'

但我得到(注意第一列缺少前缀并且分隔符已删除):

numberinput_file.dateinput_file.customerinput_file.keyinput_file.amount

预期输出:

input_file.number;input_file.date;input_file.customer;input_file.key;input_file.amount

您的 gsub 会粗暴地将输入中任意位置的非字母字符替换为前缀 - 包括您的列分隔符。

print 可以缩写为脚本最后的常用习语 1;这只是表示“此条件为真;对每一行执行默认操作(即全部打印)”,尽管这只是风格上的更改。

awk -F';' 'NR==1{
    sub(/^/, "input_file."); gsub(/;/, ";input_file."); }
  1' filename

如果您想对多个文件执行此操作,可能会在其周围放置一个 shell 循环。如果您只想将所有内容连接到标准输出,您可以一次性将所有文件提供给 Awk(在这种情况下,您可能不想在第一个文件之后打印任何文件的 header 行;也许改变1NR==1 || FNR != 1).

我会按照以下方式使用 GNU AWK,令 file.txt 内容为

number;date;customer;key;amount
1;2;3;4;5
6;7;8;9;10

然后

awk 'BEGIN{FS=";";OFS=";input_file."}NR==1{="input_file." }{print}' file.txt

输出

input_file.number;input_file.date;input_file.customer;input_file.key;input_file.amount
1;2;3;4;5
6;7;8;9;10

说明:我将 OFS 设置为 ; 后跟前缀。然后在第一行中,我将前缀添加到第一列,这会触发字符串重建。没有在任何其他行中进行任何修改,因此它们 print 按原样编辑。

(在 GNU Awk 5.0.1 中测试)

在任何 awk 中都是:

$ awk 'NR==1{gsub(/^|;/,"&input_file.")} 1' file
input_file.number;input_file.date;input_file.customer;input_file.key;input_file.amount

但是 sed 的存在是为了进行这样的简单替换,例如使用具有 -E 的 sed 来启用 ERE(例如 GNU 和 BSD sed):

$ sed -E '1s/^|;/&input_file./g' file
input_file.number;input_file.date;input_file.customer;input_file.key;input_file.amount

如果您使用的是 GNU 工具,那么您可以使用以上任一方法通过以下任一方法一次性更改所有 CSV 文件:

awk -i inplace 'NR==1{gsub(/^|;/,"&input_file.")} 1' *.csv
sed -i -E '1s/^|;/&input_file./g' *.csv

还有 awk 使用 for 循环和 printf:

awk 'BEGIN{FS=OFS=";"} NR==1{for (i=1; i<=NF; i++) printf "%s%s", "input_file." $i, (i<NF ? OFS : ORS)}' file
input_file.number;input_file.date;input_file.customer;input_file.key;input_file.amount