使用shell搜索文件

使用shell搜索文件,shell,Shell,我想从多个文件中创建一个单词列表。所有文件中都有关键字,前面有一组单词。例如: Keywords: engine, motor, car, etc. 我想用shell脚本列出所有这些单词 从评论中: 这是一组包含电子邮件的文本文件。每个文件都有一个标题,标题行如下: Keywords: photo, camera, color 我想用这些关键词构建一个单词包。也就是说,最后我希望有一个单词数组 (我真的希望您指的是基于unix/linux的shell) 如果你编辑你的文章,包括预期输入的例子

我想从多个文件中创建一个单词列表。所有文件中都有关键字,前面有一组单词。例如:

Keywords: engine, motor, car, etc.
我想用shell脚本列出所有这些单词

从评论中:

这是一组包含电子邮件的文本文件。每个文件都有一个标题,标题行如下:

Keywords: photo, camera, color
我想用这些关键词构建一个单词包。也就是说,最后我希望有一个单词数组

(我真的希望您指的是基于unix/linux的shell)

如果你编辑你的文章,包括预期输入的例子(2个小样本文件将是完美的)和你需要的“文字袋”的输出,这将有助于在将来得到一个合理的答案。另外,您可以在一个问题上使用5个标记,所以请将基本操作系统指定为unix/linux/Windows/other?和一种可能的编程语言。请注意,当您将鼠标悬停在标记上时,您将看到有多少追随者。不要在只有几个追随者的东西上浪费有价值的标签。(并不是说你做了那件事)。追随者越多,你就越有可能找到能帮助你的人

也就是说,考虑到您在原始邮件和评论中包含的两组数据,再加上我对“单词袋”的最佳猜测,我提出以下建议:

cat carFile
other stuff
Keywords: engine, motor, car
other stuff

cat cameraFile
other stuff
Keywords: photo, camera, color
more other stuff
Keywords: road, highway, oinker
final other stuff


awk '{
       if ($0 ~ /Keywords:/) {
         line=$0
         sub(/Keywords: /, "", line)
         array[FILENAME] = array[FILENAME] ? array[FILENAME] ", " line : line
       }
      }
      END {
        for (key in array) {
          printf("%s:\t%s\n", key, array[key])
        }
      }
      ' carFile cameraFile
输出

carFile:        engine, motor, car
cameraFile:     photo, camera, color, road, highway, oinker
请注意,我故意在cameraFile中添加了car术语。其思想是处理作为awk脚本参数包含的任何文件,并根据输入文件名将任何带有“关键字:”的行添加到列表中

还请注意,您可以很容易地更改输出,只显示从关键字行检索到的值(而不显示sourceFile名称),方法是在END语句的输出处理中删除这些值,如

       for (key in array) {
          printf("%s\n",  array[key])
        }

有关awk处理的一些详细信息

FILENAME是自动提供的awk变量,对应于正在处理的当前文件

array是awk关联数组的用户定义名称。它可能是“a”或“arr”或符合awk变量命名约定的任何名称(与所有C语言派生的var名称规则相同)

sub(…)是“替换”的awk函数。我已经将输入行“$0”复制到一个名为line的var中,然后删除了关键字:行的一部分

awk通过一个隐式循环处理数据,该循环的代码位于初始{…}块内

我们扫描带有
if($0~/keywords:/)
的关键字行,然后只处理条件块中的那些行

只有在读取所有输入文件后,
END{…}
块才会“运行”。在本例中,我们循环遍历键上的数组,并打印出键值对。因为我们将数据附加到数组值中(第5行),所以会为cameraFile显示两组关键字

我希望这有帮助

另外,欢迎来到StackOverflow(S.O.)。请记住阅读常见问题解答,使用灰色三角形为好的Q/A投票,并接受最能解决您问题的答案,如果有,请按复选标记,

(我真的希望您指的是基于unix/linux的shell)

如果你编辑你的文章,包括预期输入的例子(2个小样本文件将是完美的)和你需要的“文字袋”的输出,这将有助于在将来得到一个合理的答案。另外,您可以在一个问题上使用5个标记,所以请将基本操作系统指定为unix/linux/Windows/other?和一种可能的编程语言。请注意,当您将鼠标悬停在标记上时,您将看到有多少追随者。不要在只有几个追随者的东西上浪费有价值的标签。(并不是说你做了那件事)。追随者越多,你就越有可能找到能帮助你的人

也就是说,考虑到您在原始邮件和评论中包含的两组数据,再加上我对“单词袋”的最佳猜测,我提出以下建议:

cat carFile
other stuff
Keywords: engine, motor, car
other stuff

cat cameraFile
other stuff
Keywords: photo, camera, color
more other stuff
Keywords: road, highway, oinker
final other stuff


awk '{
       if ($0 ~ /Keywords:/) {
         line=$0
         sub(/Keywords: /, "", line)
         array[FILENAME] = array[FILENAME] ? array[FILENAME] ", " line : line
       }
      }
      END {
        for (key in array) {
          printf("%s:\t%s\n", key, array[key])
        }
      }
      ' carFile cameraFile
输出

carFile:        engine, motor, car
cameraFile:     photo, camera, color, road, highway, oinker
请注意,我故意在cameraFile中添加了car术语。其思想是处理作为awk脚本参数包含的任何文件,并根据输入文件名将任何带有“关键字:”的行添加到列表中

还请注意,您可以很容易地更改输出,只显示从关键字行检索到的值(而不显示sourceFile名称),方法是在END语句的输出处理中删除这些值,如

       for (key in array) {
          printf("%s\n",  array[key])
        }

有关awk处理的一些详细信息

FILENAME是自动提供的awk变量,对应于正在处理的当前文件

array是awk关联数组的用户定义名称。它可能是“a”或“arr”或符合awk变量命名约定的任何名称(与所有C语言派生的var名称规则相同)

sub(…)是“替换”的awk函数。我已经将输入行“$0”复制到一个名为line的var中,然后删除了关键字:行的一部分

awk通过一个隐式循环处理数据,该循环的代码位于初始{…}块内

我们扫描带有
if($0~/keywords:/)
的关键字行,然后只处理条件块中的那些行

只有在读取所有输入文件后,
END{…}
块才会“运行”。在本例中,我们循环遍历键上的数组,并打印出键值对。因为我们将数据附加到数组值中(第5行),所以会为cameraFile显示两组关键字

我希望这有帮助


另外,欢迎来到StackOverflow(S.O.)。请记住阅读常见问题解答,使用灰色三角形为好的Q/A投票,并接受最能解决您问题的答案(如果有),请按复选标记,

您能详细说明文件语法吗?是不是“像”摩托食品吧?我不懂“前面有一组词”的意思。我的意思是什么