long-cluttered-filename.txt
我正在尝试通过删除与我的字符串匹配的行来进行清理delete-these-lines.txt
...
$ cat delete-these-lines.txt
context
platform
server
civicrm
site_enabled
client
redirection
cron_key
^\s*[0-9]*\s
alias
profile
install
ssl_
address
...并且通过一个简单的for
循环,我可以迭代该文件的行,如下所示:
$ for l in delete-these-lines.txt; do cat $l; done
context
platform
server
civicrm
site_enabled
client
redirection
cron_key
^\s*[0-9]*\s
alias
profile
install
ssl_
address
但当我尝试替代它时,cat
它sed
不起作用。这些都不起作用:
for l in delete-these-lines.txt; do sed -i "/$l/d" long-cluttered-filename.txt; done
for l in delete-these-lines.txt; do sed -i '/"$l"/d' long-cluttered-filename.txt; done
$l
这是变量插值的问题吗?这是for
循环的限制吗?
我看到类似的答案循环 sed 从文本文件中删除字符串列表中提供的字符串行和从文件中读取行然后删除使用while
循环,read
但如果可能的话我更愿意使用for
循环,如果不可能我想知道为什么。
答案1
如果您有两个文件,其中一个文件包含要从另一个文件中删除的字符串列表,则可以通过一个简单的操作完成整个操作grep
:
grep -v -f delete-these-lines.txt long-cluttered-filename.txt
long-cluttered-filename.txt
这将输出与 中的模式不匹配的所有字符串delete-these-lines.txt
。
请注意,如果 in 中的某些字符串long-cluttered-filename.txt
包含client
(例如123superclient456
),它仍然匹配client
并将从输出中排除。
答案2
切勿使用字母l
作为变量名,因为它看起来太像数字1
,从而使您的代码变得混乱。正如您已经知道的那样,您想做的是一个坏主意,但是请参阅https://mywiki.wooledge.org/DontReadLinesWithFor了解如何从 shell 中的文件读取行,然后将其编写为:
while IFS= read -r regexp; do
sed -i "/$regexp/d" long-cluttered-filename.txt
done < delete-these-lines.txt
但同样,不要因为已经警告过您的所有原因而这样做(而且您只是重新实现grep -v -f delete-these-lines.txt long-cluttered-filename.txt > tmp && mv tmp long-cluttered-filename.txt
效率较低、稳健性较差且可移植性较差)。