sed就地命令不能从bash中的文件中删除

时间:2015-03-08 11:31:21

标签: bash sed

我有一个bash脚本,它检查文件中的字符串模式并删除整个行i同一个文件,但不知何故它不删除该行,并且没有从命令提示符中删除任何错误.same命令从文件中删除。

#array has patterns
for k in "${patternarr[@]}
do
   sed -i '/$k/d' file.txt
done

sed版本是> 4

当这个循环完成时,我希望从file.txt中删除所有与数组中的字符串模式匹配的行

当我从命令提示符运行sed -i '/pataern/d file.txt然后它工作正常但不在bash中 提前致谢

4 个答案:

答案 0 :(得分:2)

下面:

sed -i '/$k/d' file.txt

sed脚本是单引号,它可以防止shell变量扩展。它(可能)将与

一起使用
sed -i "/$k/d" file.txt

我说"可能"因为它会做什么取决于$k的内容,它只是被代入sed代码并被解释为这样。如果$k包含斜杠,它将会中断。如果它来自一个不值得信任的源代码,那么你可以打开自己的代码注入(特别是使用GNU sed,可以执行shell命令)。

考虑k=^/ s/^/rm -Rf \//e; #

将shell变量替换为sed代码(或任何其他代码)通常是个坏主意。更好的方法是使用GNU awk:

awk -i inplace -v pattern="$k" '!($0 ~ pattern)' file.txt

或者只使用grep -v和临时文件。

答案 1 :(得分:1)

首先,你在for语句中的${patternarr[@]}周围有一个未公开的双引号。

然后你的问题是你在参数中使用单引号,使你的shell不评估引号内的$k

% declare -a patternarr=(foo bar fu foobar)
% for k in ${patternarr[@]}; do echo sed -i '/$k/d' file.txt; done
sed -i /$k/d file.txt
sed -i /$k/d file.txt
sed -i /$k/d file.txt
sed -i /$k/d file.txt

如果你用双引号替换它们,这里就是:

% for k in ${patternarr[@]}; do echo sed -i "/$k/d" file.txt; done
sed -i /foo/d file.txt
sed -i /bar/d file.txt
sed -i /fu/d file.txt
sed -i /foobar/d file.txt

答案 2 :(得分:1)

任何时候你在shell中编写循环只是为了操作文本你都有错误的方法。这可能更接近你真正应该做的事情(不需要周围的循环):

awk -v ks="${patternarr[@]}" 'BEGIN{gsub(/ /,")|(",ks); ks="("ks")} $0 !~ ks' file.txt

但是如果你向我们展示一些样本输入和预期输出,可能还有更好的方法(例如只检查1个字段而不是整行,或使用字边界,或字符串比较或....)。 p>

答案 3 :(得分:0)

您需要使用双引号在命令中插入shell变量,例如:

for k in ${patternarr[@]}; do
    sed -i "/$k/d" file.txt
done