如果文件包含特定字符串,则在特定位置插入一行

如果文件包含特定字符串,则在特定位置插入一行

我想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选项。当模式保存在变量中时,指定grepwith的模式是一个好习惯。-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 语法,所以我假设这是可以的。{} \;sedsedsedsedseda

也可以看看了解“find”的 -exec 选项

相关内容