从 CSV 文件插入回车符的 Sed 搜索和替换



我有一个文件retimp_info.csv,有两列和~500行,如下所示:

rettag, retid  
231,1    

以及包含多行和多列的文件mdb_ret_exp.csv

a,s,d,231,f,g
a,s,d,345,f,g

因此,目标是查找rettag的出现次数并将其替换为第一个文件中的retid。现在mdb_ret_exp.csv内部有多个rettag需要更换。(使用逗号,以便可以指定列,以防该数字出现在我可能不知道的其他任何地方 IE - 不同的列(。

这是我尝试过的:

while IFS="," read -r rettag retid; do
  sed -i "s/,$rettag,/,$retid,/" mdb_ret_exp.csv
done < $HOME/retimp_info.csv

它几乎可以工作,但它在每次更换时都会增加一个额外的回车符:

a,s,d,1
,f,g
a,s,d,345,f,g

我希望它仍然保留在一行上:

a,s,d,1,f,g
a,s,d,345,f,g

如何避免额外的回车?

很可能是由于您的retimp_info.csv具有DOS/Windows样式rn行尾引起的。您可以在阅读时从文件中删除它们:

cat "$HOME/retimp_info.csv" | tr -d 'r' | while IFS="," read -r rettag retid; do
  sed -i "s/,$rettag,/,$retid,/" mdb_ret_exp.csv
done

或者使用dos2unix提前将它们从文件中剥离出来,或者在文本编辑器中打开文件,选择"Unix行尾"或等效选项,然后再次保存。

你吠错了树。只需这样做:

awk '
BEGIN { FS=OFS="," }
NR==FNR { map[$1] = $2; next }
{
    for (i=1; i<=NF; i++) {
        if ($i in map) {
            $i = map[$i]
        }
    }
    print
}
' $HOME/retimp_info.csv mdb_ret_exp.csv

这将解决您当前的所有问题以及您可能尚未解决但可能会遇到的与以下方面有关的问题:

  1. 执行正则表达式而不是字符串比较,以及
  2. 您当前的方法不能在第一个或最后一个起作用的事实每行上的字段,以及
  3. 如前所述,您的 SED 循环可以在制作替代品后替换它们

除了更加强大之外,awk 方法还将比您当前的方法至少快一个数量级。另请参阅为什么使用外壳循环来处理文本被认为是不良做法。

哦,首先在输入文件上运行dos2unix或类似文件,因为它们当前具有 Windows control-M 行结尾(使用 cat -v file 查看它们(。

更新:使用了以下内容 -

while IFS="," read -r rettag retid; do sed -i "s/,$rettag,/,$retid,/g" mdb_ret_exp.csv done < $home/retimp_info.csv 工作正常,但现在在它替换正确的值(位于行/行中间(后,它会插入回车符 - 导致以下信息移动到下一行

即:
A,S,D,231,F,G

现在是——
A,S,D,1
,f,g
需要 ,f,g 保持在同一条线上...

最新更新