用 sed 替换多个特定事件

用 sed 替换多个特定事件

我有一个具有当前结构的大型 CSV 文件

380670000001,<n>,0,1970-01-01 00:00:00.00+0000,0,0,<n>,0,0

我必须更换 “<n>”在第 2 列和第 4 列中“1970-01-01 00:00:00.00+0000”
并更换“<n>”在其他列中0

目前,我正在使用awk脚本:

awk 'BEGIN{FS=OFS=","}{sub("<n>","1970-01-01 00:00:00.00+0000",$2); sub("<n>","1970-01-01 00:00:00.00+0000",$4);  gsub("<n>", 0); print}' input.txt > output.txt

这可以做得更优雅吗sed

答案1

我不这么认为。在 sed 中,没有字段之类的东西,因此您必须使用正则表达式进行硬计数。可以做到,但不够优雅:

r='1970-01-01 00:00:00.00+0000'
sed -E "s/^([^,]*,)<n>/\1$r/;s/^(([^,]*,){3})<n>/\1$r/;s/<n>/0/g" file

(您可能想看看使用 \1 保留模式的一部分如果您不知道反向引用。)

可以通过设置 shell 变量来清理 awk,就像我上面对 sed 所做的那样,然后将其传递给 awk。所以你的 awk 脚本现在主要只包含逻辑:

r='1970-01-01 00:00:00.00+0000'
m='<n>'
awk 'BEGIN{FS=OFS=","}{sub(m,r,$2);sub(m,r,$4);gsub(m,"0")}1' r="$r" m="$m" file

短一点:

awk -F, '{sub(m,r,$2);sub(m,r,$4);gsub(m,"0")}1' OFS=, r="$r" m="$m" file

答案2

不,使用 sed 不能更优雅地完成此操作,但在 awk 中可以更优雅地完成此操作:

$ awk '
    BEGIN { FS=OFS=","; n="<n>"; r="1970-01-01 00:00:00.00+0000" }
    { for (i=2;i<=4;i+=2) if ($i == n) $i=r; gsub(n,0) }
1' file
380670000001,1970-01-01 00:00:00.00+0000,0,1970-01-01 00:00:00.00+0000,0,0,0,0,0

答案3

尝试使用下面的 awk 命令

echo "380670000001,<n>,0,1970-01-01 00:00:00.00+0000,0,0,<n>,0,0"| awk -F "," '{for(i=1;i<=NF;i++){if(i ~ /2|4/){gsub("<n>","1970-01-01 00:00:00.00+0000",$i)}else{gsub("<n>","0") }}}1'

输出

380670000001,0,0,1970-01-01 00:00:00.00+0000,0,0,0,0,0

相关内容