我的情况是:
我有一个很长的文本字符串,包含特殊字符,它出现在各种文件的长行中。包含该字符串的文件遍布整个文件系统(Linux)。字符串可能出现在文件中的各个行号上,但每个文件出现一次。但是,该字符串包含一个特定的模式,我可以键入该模式以识别整个字符串。
我知道如何通过使用GREP -lir mystringprefix / path键入字符串的'prefix'来查找包含字符串的文件的名称。
我知道如何使用GREP和SED使用grep -n“prefix”来确定文件中字符串的行号。 sed -n“s / ^([0-9] )[:]。 / \ 1 / p”。
我知道如何使用SED使用sed -i xd / path / file(x是要删除的行号)删除包含感兴趣字符串的文件中的行。
我的问题是如何将所有这些放在一起以确定哪些文件包含模式,将名称传递给GREP以确定文件中的行号,然后将名称和行号传递给SED以删除行?
我需要以这样的方式执行此操作:从文件系统中的某个位置开始,然后以递归方式搜索/删除。
谢谢。
答案 0 :(得分:2)
非常简单:
for file in "$(grep -lir 'prefix' /path/)" ; do
sed -ibk -e '/prefix/d' "$file"
done
我们假设grep -lir prefix /path/
返回以换行符分隔的文件名列表,并且您的前缀模式也是sed
可以理解的内容。
我不需要在此确定行号,因为我告诉sed
找到与prefix
匹配的行并直接删除它们。然而,for file in "$(grep ...)"
构造有点不安全,因为攻击者可以创建一个文件名,这会导致它做一些你不期望的事情。最好说:
grep -lir 'prefix' /path/ --null | while IFS= read -r -d '' file ; do
sed -ibk -e '/prefix/d' "$file"
done
虽然请注意,在while
循环体中分配的变量将无法生存。
答案 1 :(得分:0)
模式区分大小写。
grep -Zlr 'mystringprefix' /path/ | xargs -0 sed -i '/mystringprefix/d'