我是新来的,还没有发布太多内容,我会尽力把这一点说清楚。
我想执行涉及三个文件的查找和替换: 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 脚本之前检查和/或编辑它。