Sed 如果存在';稍后将在文件内容中找到匹配项

Sed 如果存在';稍后将在文件内容中找到匹配项,sed,Sed,如果我的输入文件有一个特定的单词,我想在我的输出上加一行。 然而,如果我只是在寻找特定的字符串,那么据我所知,已经太晚了。第一行已经在输出中,我不能再对它进行前置了 下面是一个输入示例 one two two three 如果我能找到一行,比如说,单词two,我想在第一行之前添加一行新行,例如FOUND。我只想让那一行前置一次,即使有几场比赛 因此,没有任何两个的输入文件将保持不变,上面的示例文件将变为: FOUND one two two three 我知道如何使用I\进行前置,但无法正确

如果我的输入文件有一个特定的单词,我想在我的输出上加一行。 然而,如果我只是在寻找特定的字符串,那么据我所知,已经太晚了。第一行已经在输出中,我不能再对它进行前置了

下面是一个输入示例

one
two
two
three
如果我能找到一行,比如说,单词
two
,我想在第一行之前添加一行新行,例如
FOUND
。我只想让那一行前置一次,即使有几场比赛

因此,没有任何
两个
的输入文件将保持不变,上面的示例文件将变为:

FOUND
one
two
two
three
我知道如何使用
I\
进行前置,但无法正确获取上下文。据我所知,这将是:

1{
/two/{   # This will will search "two" in the first line, how to look for it in the whole file ?
1i\
FOUND
    }
}
编辑:

我知道如何使用其他语言/方法,这不是我的问题

Sed具有可同时处理多行、追加/前置行的高级功能,并且不限于替换。我有一个sed文件,其中已经填充了用于修改python源文件的表达式,这就是为什么我宁愿避免使用其他内容。如果使用某个类,我希望能够在文件开头添加导入。

Perl解决方案:

perl -i.bak -0077 -pE 'say "FOUND" if /two/;' in_file
Perl one liner使用以下命令行标志:
-p
:一次循环输入一行,默认情况下将其分配给
$\uu
。在每次循环迭代后添加
print$\uuz

-i.bak
:就地编辑输入文件(覆盖输入文件)。在覆盖之前,通过在原始文件的名称后附加扩展名
.bak
,保存原始文件的备份副本。
-E
:告诉Perl在线查找代码,而不是在文件中。还启用所有可选功能。在这里,启用

-0777
:整个文件都是Slurp文件

另请参见:
Perl解决方案:

perl -i.bak -0077 -pE 'say "FOUND" if /two/;' in_file
Perl one liner使用以下命令行标志:
-p
:一次循环输入一行,默认情况下将其分配给
$\uu
。在每次循环迭代后添加
print$\uuz

-i.bak
:就地编辑输入文件(覆盖输入文件)。在覆盖之前,通过在原始文件的名称后附加扩展名
.bak
,保存原始文件的备份副本。
-E
:告诉Perl在线查找代码,而不是在文件中。还启用所有可选功能。在这里,启用

-0777
:整个文件都是Slurp文件

另请参见:

sed用于对单个字符串执行s/old/new操作,这不是您要尝试的,因此您不应该费心尝试使用sed。有很多方法可以做到这一点,这一种方法将非常高效、健壮并且可移植到所有Unix系统:

$ grep -Fq 'two' file && echo "FOUND"; cat file
FOUND
one
two
two
three
要对流而不是(或附加)文件进行操作,而无需将整个输入读取到内存中:

awk 'f{print; next} {buf[NR]=$0} /two/{print "FOUND"; for (i=1;i<=NR;i++) print buf[i]; f=1}'

awk'f{print;next}{buf[NR]=$0}/two/{print“FOUND”;for(i=1;ised用于对单个字符串执行s/old/new操作,这不是您试图执行的操作,因此您不应该费心尝试使用sed。有很多方法可以做到这一点,这一方法将非常高效、健壮,并且可移植到所有Unix系统:

$ grep -Fq 'two' file && echo "FOUND"; cat file
FOUND
one
two
two
three
要对流而不是(或附加)文件进行操作,而无需将整个输入读取到内存中:

awk 'f{print; next} {buf[NR]=$0} /two/{print "FOUND"; for (i=1;i<=NR;i++) print buf[i]; f=1}'

awk'f{print;next}{buf[NR]=$0}/two/{print“FOUND”;for(i=1;ised是一个流编辑器,我正在编辑一个流。sed不仅仅用于编辑流,你在问题中多次提到你在操作一个文件——“如果我的输入文件有一个特定的单词,我想在输出的顶部添加一行”和“如何在整个文件中查找它”和“修改python源文件”。如果您需要一个适用于流的解决方案(或另外),请修正您的问题。我同时更新了我的答案。抱歉,我的回答不够明确。因为您说“sed用于对单个字符串执行s/old/new”.Sed代表“流编辑器”,它的主要目标是操纵文本流,因此将其简化为仅仅进行替换是不正确的。是的,我正在更改一个文件,但操纵一个文件或流与sed是完全相同的。@liberforce我知道sed的意思,我已经使用它将近40年了,我是这个论坛上的顶尖人物之一从流或文件来看,“string”并不意味着“file”。我的观点是,如果您使用的是sed构造,而不仅仅是那些需要对字符串进行简单替换的构造(即s、g和p(带-n))例如,尝试在整个文件中匹配一个regexp,然后在该文件的前面插入一个字符串,那么sed不是该作业的最佳工具。sed可能不是该作业的最佳工具,但我在一个sed文件中已经有一组表达式,我更愿意在该脚本中添加几行(即使它有点复杂和次优),而不是事后使用单独的方法。我问题的重点是“sed是否可行,以及如何实现?”,而不是“sed是否是此项工作的最佳工具?”。sed是一个流编辑器,我正在编辑流。sed不仅用于编辑流,而且您在问题中多次表示您正在操作一个文件-“如果我的输入文件有一个特定的单词,我想在我的输出上加一行”和“如何在整个文件中查找”以及“修改python源文件”。如果您需要一个适用于streams的解决方案(或另外)然后把你的问题改成这样。我同时更新了我的答案。对不起,我的回答不够明确。因为你说“sed用于对单个字符串执行s/old/new”。sed代表“流编辑器”“,它的主要目标是操纵文本流,因此将其简化为仅进行替换是不正确的。是的,我正在更改一个文件,但操纵一个文件或strea