我想line 2
在文件中某处包含特定字符串的每个文件中插入一个字符串。
喜欢
sed '1 a #This is just a commented line' -i
但仅当文件包含字符串时:
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">
答案1
假设你的命令,
sed -i '1 a #This is just a commented line'
适用于给定文件。
要将其应用于某个文件,somefile
,如果该文件包含字符串<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">
,您可以使用
if grep -q -F '<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">' somefile
then
sed -i '1 a #This is just a commented line' somefile
fi
选项-q
导致grep
实用程序在第一个匹配处停止,并且不输出任何内容(我们只对退出状态感兴趣)。该-F
选项将使grep
给定模式视为字符串而不是正则表达式。
要将其应用于当前目录中的所有文件(跳过非常规文件或常规文件的符号链接的文件):
pattern='<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">'
for name in ./*; do
[ ! -f "$name" ] && continue
if grep -q -F -e "$pattern" "$name"; then
sed -i '1 a #This is just a commented line' "$name"
fi
done
我在这里使用-e "$pattern"
, 和-e
选项。当模式保存在变量中时,指定grep
with的模式是一个好习惯。-e
可能存在变量值以破折号开头的情况(显然不是在这个特定问题中),grep
如果-e
不使用,这会令人困惑,使其认为该模式实际上是某个命令行选项。
要对当前目录中或当前目录下的所有文件执行此操作:
pattern='<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">'
find . -type f -exec sh -c '
pattern=$1; shift
for name do
if grep -q -F -e "$pattern" "$name"; then
sed -i "1 a #This is just a commented line" "$name"
fi
done' sh "$pattern" {} +
这将为sh -c
批量找到的文件执行一个简短的内联脚本,将模式作为第一个命令行参数传递给脚本,并将找到的路径名作为其余参数传递。
或者,让其find
用作grep
测试,然后sed
在通过测试的文件上执行,
pattern='<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">'
find . -type f \
-exec grep -q -F -e "$pattern" {} \; \
-exec sed -i '1 a #This is just a commented line' {} +
通过在上面命令的末尾使用{} +
而不是,我们一次给出尽可能多的输入文件,而不是为每个文件执行一次。这需要 GNU才能正常工作,但由于您已经在命令中使用了 GNU 语法,所以我假设这是可以的。{} \;
sed
sed
sed
sed
sed
a
也可以看看了解“find”的 -exec 选项