输出文件名和“找到的字符串”位于输出文件的同一行

输出文件名和“找到的字符串”位于输出文件的同一行

半新手。尝试使用 awk 脚本实现自动化。理论上应该很简单。

文件集,全部以 .lst 结尾。每个文件中都有一行(数百行)带有特定的字符串 - 比如说单词“Wall”。我希望做的是最终得到一个文件,其中每行以(i)文件名和(ii)输出字符串结尾。我有“部分”单独工作,但还没有弄清楚如何将它们组合在一起(以生成通用输出文件)。

所以,假设我有 3 个 *.lst 文件(file1.lst、trash.lst、blah.lst)。我可以使用类似以下内容将文件名输出到文件中(毫无疑问有更好的方法,但它有效......):

      ls -l *.lst | awk '{ print "File: " $9 }' > filenames.dat

而且,可以轻松地将每个 *.lst 文件中包含“Wall”的行输出到公共文件,使用类似以下内容:

 awk '/Wall/{print}'  *.lst > wallvals.dat

我可以通过各种方式对两者进行后处理和合并,但我想弄清楚如何使用 awk 在一行中完成这一切。因此,生成的输出文件可能如下所示:

 File: file1.lst   Wall data 4.54
 File: trash.lst   Wall data 3.44
 File: blah.lst    Wall data 333.66

我尝试过各种管道方法,或者在 awk 参数中嵌套各种位 - 但我尝试过的任何方法都不起作用(除非目的是生成错误消息)。

提前赞赏明显的指针......

答案1

当前正在处理的文件的文件名awk可在特殊变量中找到FILENAME。这意味着您可以awk像这样调整第二个命令:

awk '/Wall/ { printf "%s:%s\n", FILENAME, $0 }' *.lst

或者,如果你不喜欢printf

awk '/Wall/ { print FILENAME ":" $0 }' *.lst

或者,通过使用输出字段分隔符OFS

awk -v OFS=: '/Wall { print FILENAME, $0 }' *.lst

这会输出文件名和与模式匹配的行,中间有一个冒号。

这与以下grep命令的作用相同:

grep -H 'Wall' *.lst

...有一个微小的区别,即此处的搜索字符串用作基本正则表达式而不是扩展正则表达式(但这在本例中并不重要)。该-H选项不是标准的,如果grep给出多个文件名则没有必要。grep 'Wall' /dev/null *.lst将是编写相同命令的更标准方法(如果给出多个路径名,实用程序总是输出每个匹配的文件名)。

如果你想要精确的您在问题中提到的输出格式,然后修改printf格式字符串:

awk '/Wall/ { printf "File: %s\t%s\n", FILENAME, $0 }' *.lst

或者,

awk '/Wall/ { print "File: " FILENAME "\t" $0 }' *.lst

这会输出字符串File:,后跟文件名、制表符和行。

关于你的第一个命令:它是一般来说解析 的输出是一个坏主意ls,部分是因为它几乎总是不必要且不雅观,部分是因为 的输出ls主要用于查看(文件名可能对其进行了额外的格式化)。它几乎总是意味着您将无法读取所有有效的文件名。看为什么*不*解析`ls`(以及该怎么做)?

相关内容