多个 grep 分隔符并显示文件信息

Multiple grep separator and display file information

我想在多个分隔符的文件中grep多个信息,并显示文件信息,只有一个命令。

./WBL-FILE-S-1-execution79065.html
./WBL-FILE-S-1-execution79066.html
./WBL-FILE-S-1-execution79067.html

如果我这样做:

find . -type f -name « *WBL-FILE* » | xargs grep "Fichier lu"

我得到的结果如下:

./WBL-FILE-S-1-execution79065.html:<td title="Message">Fichier&nbsp;lu&nbsp;/opt/data/in/bl/000334_iwel1C010116730.blc.TRT</td>
./WBL-FILE-S-1-execution79065.html:<td title="Message">Fichier&nbsp;lu&nbsp;/opt/data/in/bl/000312_iwel1C010116727.blc.TRT</td>
./WBL-FILE-S-1-execution74707.html:<td title="Message">Fichier&nbsp;lu&nbsp;/opt/data/in/bl/000420_iwel1C010116284.blc.TRT</td>

目标是获取文件日期、文件名、XXXXXX_iwel 编号和 CXXXXXXXXX 编号。

示例:

2021-07-13 13:47 WBL-FILE-S-1-execution79065.html 000334 010116730
2021-07-13 14:48 WBL-FILE-S-1-execution79065.html 000312 010116727
2021-07-14 14:49 WBL-FILE-S-1-execution74707.html 000420 010116284

我几乎成功提取了不同的部分,但是之后,我无法获取原始文件的“ls”(日期)信息。

有没有办法只用一行命令组合来做到这一点?

谢谢

如果要添加文件的日期,grep 将不再适用。此外,提取 XXXXXX_iwel 和 CXXXXXXXXX 并打印这些数字 在同一行 是不可能的grep一个人。

因此我会切换到 perl:

perl -nle 'use POSIX "strftime";
BEGIN { sub mtime { strftime "%Y-%m-%d %H:%M:%S", localtime((stat $ARGV)[9]) } }
/Fichier&nbsp;lu.*?(\d+)_iwel.*?C(\d+)/ && print join " ", mtime, $ARGV, , '

因为你所有的文件都在同一个目录下,你可以使用

perl ... *WBL-FILE*

对于递归文件搜索,请使用 find -exec 而不是 find | xargs。这不仅效率更高,而且在某些文件名包含空格或特殊符号(如 "'\.

的情况下也更安全
find -type f -name '*WBL-FILE*' -exec perl ... {} +

对于每个文件,您可以通过一个 awk 命令显示您需要的信息。

awk 'match([=10=], /Fichier&nbsp;lu.*[^0-9]([0-9]*)_iwel[^C]*C([0-9]*)/, array) { date_command="date +\"%Y-%m-%d %H:%M:%S\" --date @$(stat -c %Y " FILENAME ")"; date_command | getline formatted_date; close(date_command); print formatted_date, FILENAME, array[1], array[2]}' /path/to/file

为了清楚起见,可以这样重写:

awk 'match([=11=], /Fichier&nbsp;lu.*[^0-9]([0-9]*)_iwel[^C]*C([0-9]*)/, array) {
  date_command="date +\"%Y-%m-%d %H:%M:%S\" --date @$(stat -c %Y " FILENAME ")";
  date_command | getline formatted_date;
  close(date_command);
  print formatted_date, FILENAME, array[1], array[2]
}'

基本上它做了三件事:

  • 它匹配包括Fichier&nbsp;lu在内的所有行,并将XXXXXX_iwelCXXXXXXXXX的数字捕获到一个数组中
  • 它调用命令行获取具有所需格式的文件的修改日期
  • 它在同一行打印你想要的所有信息

当然可以插在find之后

find . -name "*WBL-FILE*" | xargs awk 'match([=12=], /Fichier&nbsp;lu.*[^0-9]([0-9]*)_iwel[^C]*C([0-9]*)/, array) { date_command="date +\"%Y-%m-%d %H:%M:%S\" --date @$(stat -c %Y " FILENAME ")"; date_command | getline formatted_date; close(date_command); print formatted_date, FILENAME, array[1], array[2]}'

结果:

2021-07-28 10:45:50 ./WBL-FILE-S-1-execution79065.html 000334 010116730
2021-07-28 10:45:50 ./WBL-FILE-S-1-execution79065.html 000312 010116727
2021-07-28 10:46:41 ./WBL-FILE-S-1-execution74707.html 000420 010116284

旁注

我使用了 match 函数,它是 GNU Awk 的一部分,也称为 gawk。如果你没有,它仍然可以,但它需要另一种方式来捕获字符串。

最棘手的部分可能是获取日期的命令,因为我们需要为该命令构建一个字符串,然后调用它,然后将结果存储在一个变量中。有点乱。它还需要一个两步过程:以大纪元时间获取日期(即从 1970-01-01 开始的秒数),然后使用 YYYY-MM-DD HH:MM:SS 格式格式化此值。另一方面,您可以非常轻松地调整这些步骤。例如,您可以通过更改发送到 date. Or you can display the creation date instead of the last modification date by changing the -c %Y option sent to stat.

+\"%Y-%m-%d %H:%M:%S\" 字符串以其他格式显示日期

该命令对包含空格的文件名和文件夹不可靠。要解决此问题,首先您可以在日期调用期间使用丑陋的语法将 $(stat -c %Y " FILENAME ")" 替换为 $(stat -c %Y '"'"'" FILENAME "'"'"')"。哎呀。这是由于我们如何在一行中构建字符串。其次,您可以使用这些命令中的任何一个来确保正确传递文件名(为简化起见,假设 awk 脚本存储在 AWKSTRING 变量中)。

find . -name "*WBL-FILE*" -print0 | xargs -0 awk "$AWKSTRING"
find . -name "*WBL-FILE*" -exec awk "$AWKSTRING" {} \;
find . -name "*WBL-FILE*" -exec awk "$AWKSTRING" {} +

后者可能比其他的更优化一些,但并非所有 find 版本都支持它。