所以基本上我有一个1500个名字的原始列表,每个名字都有一个4位数字。我有另一个文件,其中包含这1500个名称中的200个,并带有一个与之关联的新4位数字。我需要用这个新号码替换旧号码。
我有一个文件original.txt,其中包含1500行文字,如下所示:
名称AYxxxx
name2 AYxxxx
name3 AYxxxx
......
name1500 AYxxxx
xxxx是一个4位数字,AY是出现在每4位数字前面的字符串
我有一个包含200行的updated_file.txt:
名称AYzzzz
name40 AYzzzz
name1300 AYzzzz
zzzz是一个不同的4位数字。我需要取新的数字(zzzz)并替换original.txt中的旧数字(xxxx)。
所以在原文中,我需要的是文本的样子:
名称AYzzzz
name2 AYxxxx
name40 AYzzzz
name1300 AYzzzz
name1500 AYxxxx
我在考虑做这样的事情:
names=updated.txt
while read names
do
sed -E "s/$names[^AY.*]/$names/" original.txt
done < "$names"
答案 0 :(得分:2)
您可以从更新字段生成sed脚本,例如
sed 's:\(.*AY\)\d\+:/\1/s_.*_&_:' UPDATEFILE > SEDUPDATE.SED
然后在原始文件上运行生成的脚本,如:
sed -f SEDUPDATE.SED ORIGINAL_FILE
答案 1 :(得分:2)
我赞成了@ ZoltBotykai的答案,但这是一个小修改,希望稍微更精确和便携。
sed 's:\(.*AY\)[0-9][0-9]*$:s_^\1[0-9]*$_&_:' updated_file.txt |
sed -f - -i original.txt
如果您使用* BSD我相信您需要在-i
选项中添加一个空参数才能使其正常工作。测试时删除此选项,以便在屏幕上而不是在目标文件中看到生成的输出。
我在某种程度上收紧了正则表达式,并将\d\+
(这是最新的Perl扩展,对于“recent”的进化规模)更改为希望甚至可以在HP-UX等上工作的东西。
另一方面,一些古老的sed
实现不支持带有破折号的-f
选项来从标准输入读取生成的脚本;然后,您需要恢复将生成的脚本存储在临时文件中。
如果您的实际数据包含下划线,则必须在生成的脚本中使用不同的分隔符。 s
命令后面的字符可以是任何字符,但在替换正则表达式或替换文本中不得出现(未引用)分隔符。
答案 2 :(得分:0)
尝试以下方法:
while read old new ; do
sed -i "s/$old \([^ ]*\)/$new \1/" original.txt
done < updated_file.txt
使用-i
选项 警告,它会自动更新您的original.txt
文件。不要忘记先制作备份副本。