sed - 使用 file1 查找 file2 中包含的 file3 行的替换内容

sed - 使用 file1 查找 file2 中包含的 file3 行的替换内容

我是新来的,还没有发布太多内容,我会尽力把这一点说清楚。

我想执行涉及三个文件的查找和替换: find.csv 标识包含字符串的行。我想用replace.csv 中的一行替换整行。第三个文件是 mainfile.csv,其中包含大约 1000 行。

这是我到目前为止所拥有的,但我收到一条错误消息:

sed "s/$(cat find.csv)/$(cat replace.csv)/" mainfile.csv > out.csv
sed: 1: "s/CHL_13_R4 
DCK_09_R4  ...": unterminated substitute pattern

这些文件的内容如下:

find.csv
CHL_13_R4 
DCK_09_R4 
DCK_10_R4 
DCK_11_R4 
DCK_13_R4 

replace.csv
CHL_13_R12,CHL_13,R12,10/14/2014
DCK_09_R12,DCK_09,R12,10/14/2014
DCK_10_R32,DCK_10,R32,10/14/2014
DCK_11_R21,DCK_11,R21,10/14/2014

主文件包含与replace.csv 中相同的条目,但大约有30 个需要更新。因此,以第一行为例。 mainfile.csv 中具有“CHL_13_R4”的行需要替换为 CHL_13_R12,CHL_13,R12,10/14/2014

谢谢您的帮助!

答案1

首先从这两个文件创建一个 sed 脚本:

paste -d$'\t' find.csv replace.csv | 
    sed -e 's:/:\\/:g; s:\t:/:; s:^:s/:; s:$:/g;:' > myscript.sed

这会将所有出现的字符串替换find.csv为 中的字符串replace.csv。如果其中的任何行find.csv包含制表符,则它将失败,因为该字符被用作paste连接行之间的分隔符。

输出看起来像这样:

s/CHL_13_R4/CHL_13_R12,CHL_13,R12,10\/14\/2014/g;
s/DCK_09_R4/DCK_09_R12,DCK_09,R12,10\/14\/2014/g;
s/DCK_10_R4/DCK_10_R32,DCK_10,R32,10\/14\/2014/g;
s/DCK_11_R4/DCK_11_R21,DCK_11,R21,10\/14\/2014/g;
s/DCK_13_R4//g;

(请注意,最后一行没有替换。那是因为你find.csv有 5 行,而你replace.csv只有 4 行)

如果您想替换包含以下字符串的整行find.csv

paste -d$'\t' find.csv replace.csv | 
    awk -F$'\t' '{gsub(/\//,"\\/"); print "/"$1"/ s/^.*/"$2"/;"}' > myscript.sed

该版本的输出如下所示:

/CHL_13_R4/ s/^.*/CHL_13_R12,CHL_13,R12,10\/14\/2014/;
/DCK_09_R4/ s/^.*/DCK_09_R12,DCK_09,R12,10\/14\/2014/;
/DCK_10_R4/ s/^.*/DCK_10_R32,DCK_10,R32,10\/14\/2014/;
/DCK_11_R4/ s/^.*/DCK_11_R21,DCK_11,R21,10\/14\/2014/;
/DCK_13_R4/ s/^.*//;

无论如何,无论哪个版本最适合您,生成myscript.sed脚本后,请在您的mainfile.csv

sed -f myscript.sed mainfile.csv

-i(如果您想对 进行“就地”编辑,则可以选择使用mainfile.csv

注意:可以在不使用临时文件(例如myscript.sed保存脚本)的情况下执行此操作。大多数版本的 sed 都可以从标准输入运行脚本。但这种方式允许您在主文件上运行生成的 sed 脚本之前检查和/或编辑它。

相关内容