【发布时间】:2015-05-18 05:44:45
【问题描述】:
我一直在尝试使用 csv 对两个文本文件进行批量查找和替换。我已经看到了 SO 建议的问题,但似乎没有人回答我的问题。
我为我要修改的两个文本文件创建了两个变量。 csv 有两列和数百行。第一列包含文本文件中已有的字符串(没有空格),需要用第二列同一行中的相应字符串替换。
作为测试,我尝试了脚本
#!/bin/bash
test1='long_file_name.txt'
find='string1'
replace='string2'
sed -e "s/$find/$replace/g" $test1 > $test1.tmp && mv $test1.tmp $test1
这是成功的,除了我需要对 csv 中的每一行执行一次,使用每行中 csv 给出的值。我的预感是我的 while 循环被错误地使用了,但我找不到错误。当我执行下面的脚本时,我得到了命令行提示符,这让我觉得发生了一些事情。当我检查文本文件时,什么都没有改变。
这两个文本文件、这个脚本和 csv 都在同一个文件夹中(当我这样做时,它也是我的工作目录)。
#!/bin/bash
textfile1='long_file_name1.txt'
textfile2='long_file_name2.txt'
while IFS=, read f1 f2
do
sed -e "s/$f1/$f2/g" $textfile1 > $textfile1.tmp && \
mv $textfile1.tmp $textfile1
sed -e "s/$f1/$f2/g" $textfile2 > $textfile2.tmp && \
mv $textfile2.tmp $textfile2
done <'findreplace.csv'
在我看来,这段代码应该做我想让它做的事情(但不是);也许我误解了一些基本的东西(我是 bash 脚本的新手)?
csv 看起来像这样,但有数百行。所有 a_i 都应替换为下一列中对应的 b_i。
a_1 b_1
a_2 b_2
a_3 b_3
注意事项:所有字符串实际上都包含下划线,以防万一这会影响某些内容。我试过用大括号将变量名包裹在 ${var} 中,但它仍然不起作用。
我很欣赏这些解决方案,但我也很想知道为什么上述方法不起作用。 (另外,我会投票给每个人,但我缺乏这样做的声誉。但是,我很感激你的回答,并且我从你的回答中学到了很多东西!)
【问题讨论】:
-
您可以粘贴您传递的 csv 文件的样本吗?否则您的代码应该按原样工作..另外注意:您可以使用
sed -i "s/$f1/$f2/g" $textfile1来避免创建中间 .tmp 文件。使用选项-ised 将查找、替换和覆盖修改后的文件 -
@sa77 除了
sed -i确实创建了一个中间文本文件!另外,并不是所有的sed都有效,经常是语法错误。 -
原来我使用 TextEdit 创建的 csv 有问题;使用 Sublime 再次创建 csv 后,该脚本有效。再次感谢大家!我知道
-i标签,但更喜欢使用第二个答案here 给出的解决方案 -
对于任何可能感兴趣的人,上面给出的原始代码可以很好地完成我描述的任务。