Regex 如何更新“*”的内容。txt";多个子目录中的文件

Regex 如何更新“*”的内容。txt";多个子目录中的文件,regex,perl,grep,Regex,Perl,Grep,我有一个目录名“technology”,其中有多个子目录,每个子目录至少有一个*.txt文件 每个“*.txt”文件都有一行以单词“how_to_repeat”开头,之后可以有任何其他字符串值,但它的内容将只在一行 我使用find查找其中包含“how_to_repeat”值的文件,如下所示 find . -name '*.txt' -exec grep -H 'how_to_repeat' {} \; |wc -l 127 现在,, 我的问题是如何更新每个“*.txt”文件的内容,使其将以“h

我有一个目录名“technology”,其中有多个子目录,每个子目录至少有一个*.txt文件

每个“*.txt”文件都有一行以单词“how_to_repeat”开头,之后可以有任何其他字符串值,但它的内容将只在一行

我使用find查找其中包含“how_to_repeat”值的文件,如下所示

find . -name '*.txt' -exec grep -H 'how_to_repeat' {} \; |wc -l
127
现在,, 我的问题是如何更新每个“*.txt”文件的内容,使其将以“how_to_repeat”字开头的完整行替换为常量字符串,即“how_to_repeat=运行测试数据”

Perl脚本正在工作,但不适用于整行

perl -p -i -e 's/how_to_repeat /how_to_repeat= Run testing data  /'   `find ./ -name *.txt`

想知道它如何能取代整个生产线

考虑到
find
在这里是非常基本的,您实际上只需要
grep
和一行简单的Perl代码

grep --include=\*.txt -rlH . -e 'how_to_repeat' | xargs 
    perl -i.bak -wpe's/how_to_repeat\K.*/= Run testing data/'
-r
(或
-r
)递归搜索路径(
),而
-l
--具有匹配项的文件
)仅返回此处所需的文件名。除了
——include
之外,
grep
中还有更多选项,允许用户更精确地定制要搜索或不搜索的文件/目录

然后
xargs
将这些返回的文件名提供给Perl程序

如果您有更复杂的文件查看标准,那么
find
当然会有所帮助

评论

  • \K
    会删除它前面的所有匹配项,因此我们不需要替换它们;请参阅“环顾断言”。然后,行的其余部分与
    *
    匹配,并因此被替换

  • -i
    更改文件,但
    .bak
    使其保留备份

  • 可以单独使用shell glob构建文件列表,然后您可以将其直接传递给Perl one-liner,因为程序不会更改找不到模式的文件

    首先使用
    grep
    过滤文件列表的速度应该更快,但您只会注意到,对于许多文件,特别是如果没有很多文件具有该短语(因此没有多少文件被处理两次)


问题中的正则表达式不起作用,因为该行的其余部分从未匹配过,因此它确实没有被替换;它将与添加到模式末尾的
*
一起工作,如上图所示。

鉴于
查找
在这里非常基本,您实际上只需要
grep
和一行简单的Perl

grep --include=\*.txt -rlH . -e 'how_to_repeat' | xargs 
    perl -i.bak -wpe's/how_to_repeat\K.*/= Run testing data/'
-r
(或
-r
)递归搜索路径(
),而
-l
--具有匹配项的文件
)仅返回此处所需的文件名。除了
——include
之外,
grep
中还有更多选项,允许用户更精确地定制要搜索或不搜索的文件/目录

然后
xargs
将这些返回的文件名提供给Perl程序

如果您有更复杂的文件查看标准,那么
find
当然会有所帮助

评论

  • \K
    会删除它前面的所有匹配项,因此我们不需要替换它们;请参阅“环顾断言”。然后,行的其余部分与
    *
    匹配,并因此被替换

  • -i
    更改文件,但
    .bak
    使其保留备份

  • 可以单独使用shell glob构建文件列表,然后您可以将其直接传递给Perl one-liner,因为程序不会更改找不到模式的文件

    首先使用
    grep
    过滤文件列表的速度应该更快,但您只会注意到,对于许多文件,特别是如果没有很多文件具有该短语(因此没有多少文件被处理两次)


问题中的正则表达式不起作用,因为该行的其余部分从未匹配过,因此它确实没有被替换;它将使用添加到模式末尾的
*
,如上所述。

要匹配到行尾,只需在匹配表达式末尾添加
*

s/how_to_repeat .*/how_to_repeat= Run testing data /
因此,正如您在注释中确认的,整个命令变为:

perl -p -i -e 's/how_to_repeat .*/how_to_repeat= Run testing data  /'   `find ./ -name *.txt`

要匹配到行尾,只需在匹配表达式的末尾添加
*

s/how_to_repeat .*/how_to_repeat= Run testing data /
因此,正如您在注释中确认的,整个命令变为:

perl -p -i -e 's/how_to_repeat .*/how_to_repeat= Run testing data  /'   `find ./ -name *.txt`

如果我正确理解了问题,可能是
s/how\u to\u repeat.*/how\u to\u repeat=运行测试数据/
,请添加到答案部分。perl-p-I-e的/how\u to\u repeat./how\u to\u repeat=运行测试数据/'
查找。/-name*.txt
修复问题。完成。我不确定我对问题的解释是否正确,因此感谢您确认解决方案有效。可能是
s/how\u to\u repeat.*/how\u to\u repeat=运行测试数据/
,如果我正确理解了问题,请添加到答案部分。perl-p-I-e's/how_to_repeat.*/how_to_repeat=运行测试数据/'
find./-name*.txt
修复问题。完成。我不确定我对这个问题的解释是否正确,因此感谢您确认这个解决方案是有效的。