搜索并替换多个匹配项

时间:2015-07-11 03:29:53

标签: bash shell sed

所以我有一个包含数百万行的文件 现在我在文件中出现了诸如

=Continent
=Country
=State
=City
=Street

现在我有一个excel文件,其中我有应该替换这些事件的文本 - 例如:
= Continent 应替换为 = Asia
同样适用于其他文本

现在我正在考虑编写一个java程序来读取我的输入文件,读取映射文件以及每次出现搜索和替换。
我在这里很懒 - 想知道我是否可以使用像VIM这样的编辑器做同样的事情? 那有可能吗?
注意 - 我不想做单个文本替换 - 我有多个文本需要找到并替换,我不想进行搜索并手动替换每个。

EDIT1:
我要替换的文件内容:" 1.txt "

continent=cont_text
country=country_text

包含我要替换的值的文件:" to_replace.txt "

=cont_text~Asia
=country_text~India  

最后使用' sed'这是我的.sh文件 - 但我做错了 - 它不会替换" 1.txt"的内容。

while IFS="~" read foo bar;
do
echo $foo
echo $bar
for filename in 1.txt; do
    sed -i.backup 's/$foo/$bar/g;' $filename
done
done < to_replace.txt

3 个答案:

答案 0 :(得分:2)

您不能将$foo$bar放在单引号中,因为shell不会展开它们。您不需要for $filename in 1.txt循环,因为sed将遍历1.txt行。并且您不能在循环中使用-i.backup因为它每次都会更改备份文件而不保留原始文件。所以你的脚本应该是:

#!/bin/bash
cp 1.txt 1.txt.backup
while IFS="~" read foo bar;
do
    echo $foo
    echo $bar
    sed -i "s/$foo/=$bar/g;" 1.txt
done < to_replace.txt

输出:

$ cat 1.txt
continent=Asia
country=India

答案 1 :(得分:0)

sed用于单个行上的简单替换,而shell是一个环境,可以从中调用工具而不是操作文本的工具,因此每当你编写shell循环来操作文本时,你做错了。

只需使用发明sed和shell的同一个人发明的工具来做这样的一般文本处理工作,awk:

$ awk -F'[=~]' -v OFS="=" 'NR==FNR{map[$2]=$3;next} {$2=map[$2]} 1' to_replace.txt 1.txt
continent=Asia
country=India

答案 2 :(得分:0)

这个sed命令将在没有任何循环的情况下执行:

sed -n 's#\(^=[^~]*\)~\(.*\)#s/\1/=\2/g#p' to_replace.txt |sed -i -f- 1.txt

sed扩展正则表达式:

sed -nr 's#(^=[^~]*)~(.*)#s/\1/=\2/g#p' to_replace.txt | sed -i -f- 1.txt

<强>解释

sed命令:

sed -n 's#\(^=[^~]*\)~\(.*\)#s/\1/=\2/g#p' to_replace.txt

生成输出:

s/=cont_text/=Asia/g
s/=country_text/=India/g

然后用作管道后下一个sed的{​​{1}}脚本。

sed