将包含字符串的文件合并到一个文档中

将包含字符串的文件合并到一个文档中

基于这个脚本:

find . -name "*.txt" | grep 'LINUX/UNIX'

find . -name "*.txt" | grep 'LINUX/UNIX' | xargs cp <to a path>

这里 ,我可以 grep 文件查找某个字符串,然后将其复制到一个目录中(如果它们包含该字符串),然后将它们保留为单独的文件。如何将这些文件整理成一个连贯的文档?

示例 我的想法如下:我有一个引文存档,分布在数百个文件夹中的单独文件中,文件夹的名称是各自的主题。所以“philosophy/ontology/concepts/aletheia/notes.tex”将包含我关于aletheia等哲学概念的所有笔记。

它们都遵循某种命名约定(名称始终是:notes.tex),因此 grep 它们很容易。我可以通过 grep 搜索它们,但我希望能够有一个脚本,不仅可以找到它们,而且还可以将包含相应字符串的所有文件连接到一个大文件中。

答案1

选择*.txt当前目录或以下目录中名称匹配的常规文件,其中包含特定的细绳(不包含特定正则表达式的匹配项),并且要将这些文件按照找到的顺序连接在一起,您可以使用

find . -name '*.txt' -type f -exec grep -q -F 'LINUX/UNIX' {} \; -exec cat {} + >myfile

或者

find . -name '*.txt' -type f -exec sh -c '
    for pathname do
        grep -q -F "LINUX/UNIX" "$pathname" && cat "$pathname"
    done' sh {} + >myfile

grep此处使用该实用程序及其-q选项。这使得它不输出任何内容,但一旦给定的模式匹配,它就会以零退出状态终止,表示“成功”。我们在上面的两个命令中使用此退出状态作为测试,以仅选择那些包含字符串 的文件LINUX/UNIX

使其-Fgrep模式解释为细绳而不是作为正则表达式。这可能会使命令更快一点,但也意味着您不必担心搜索字符串,而*this*无需*特殊处理字符(因为它在正则表达式中很特殊)。

这两个命令都将串联的文件数据写入名为myfile.如果该文件已经存在,它将被截断(清空),否则将创建它。我故意选择了一个输出文件名不是可以通过命令找到find,即不以 . 结尾的命令.txt


请注意,该问题当前包含的代码似乎过滤了findwith的输出grep,然后调用cpvia xargs。这不是问题的用户自己的代码,它有几个问题。一个问题是它不会连接任何文件的内容,另一个问题是它将 应用于grep输出的路径名find而不是文件的内容。也可以看看为什么循环查找的输出是不好的做法?这是相关的。

使用问题中代码的格式来实际解决问题问题,即让find生成路径名列表,然后分别选择grep我们感兴趣的路径名,最后cat是:

find . -name '*.txt' -type f -print0 |
xargs -0 grep -lZ -F 'LINUX/UNIX' |
xargs -0 cat >myfile

.txt这会将名称以from结尾的文件的路径名列表传递find到第一个xargs作为 nul 分隔列表。该xargs实用程序调用grep这些,并grep输出包含匹配项的文件的路径名,同样作为空分隔列表。这使得它-l输出匹配文件的路径名,并将-Z其转换为空分隔列表而不是换行分隔列表。

然后,该列表由在每个文件上xargs调用的最终函数读取。像以前一样cat写入连接结果。myfile

请注意,这是解决问题的一种更尴尬的方法,有可能忘记管道阶段之间文件列表的格式,并假设运行代码的人必须使用 GNU 系统,或者至少是 GNU 工具(即它是不可移植的)。

相关内容