使用正则表达式的Sed

时间:2014-06-14 17:23:35

标签: sed

所以基本上我有一个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"

3 个答案:

答案 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文件。不要忘记先制作备份副本。