如何使用 AWK 命令获取有错误的文件名?

How to get file name which have error using AWK command?

我正在使用 SAC 工具读取 header 信息,但有些文件没有 header 信息,并且打印错误。 如果文件在工作期间没有 header 或错误,是否有任何方法可以使用 AWK 打印这些文件。我经常使用 AWK 进行数据操作,但这次失败了。

这是我的尝试:

saclst a f *2020-05*BHZ*

这是输出

GS.GS043.2020-05-18T03:52.BHZ.sac         3.37
GS.GS043.2020-05-18T09:28.BHZ.sac         3.64
GS.GS043.2020-05-18T12:09.BHZ.sac         3.42
saclst: Error determining SAC header: GS.GS043.2020-05-18T14:36.BHZ.sac
GS.GS043.2020-05-18T16:25.BHZ.sac         2.92
GS.GS043.2020-05-18T18:51.BHZ.sac         3.66

现在我想获取文件名并打印它,但 AWK 似乎无济于事;

saclst a f *2020-05*BHZ* | awk '{if (<0) print ;}' > ../test.dat

我的输出文件为空,终端显示此错误:

有什么方法可以保存这个错误以便我以后修改它吗?

saclst: Error determining SAC header: SC.LZB.2020-05-21T10:46.BHZ.sac
saclst: Error determining SAC header: SC.LZB.2020-05-21T11:57.BHZ.sac
saclst: Error determining SAC header: SC.LZB.2020-05-26T11:23.BHZ.sac
saclst: Error determining SAC header: SC.LZB.2020-05-28T10:44.BHZ.sac
saclst: Error determining SAC header: SC.QSC.2020-05-12T06:49.BHZ.sac

这是我认为您正在寻找的:

# just for demo, pipe SAC tool to awk for your actual use case
$ cat ip.txt
GS.GS043.2020-05-18T03:52.BHZ.sac         3.37
GS.GS043.2020-05-18T09:28.BHZ.sac         3.64
GS.GS043.2020-05-18T12:09.BHZ.sac         3.42
saclst: Error determining SAC header: GS.GS043.2020-05-18T14:36.BHZ.sac
GS.GS043.2020-05-18T16:25.BHZ.sac         2.92
GS.GS043.2020-05-18T18:51.BHZ.sac         3.66

# filter lines with Error based on number of fields or `Error` in 2nd field
$ awk 'NF != 2' ip.txt
saclst: Error determining SAC header: GS.GS043.2020-05-18T14:36.BHZ.sac
$ awk ' == "Error"' ip.txt
saclst: Error determining SAC header: GS.GS043.2020-05-18T14:36.BHZ.sac

# print only last field
$ awk ' == "Error"{print $NF}' ip.txt
GS.GS043.2020-05-18T14:36.BHZ.sac

如果saclst命令把带有Error的行放在stderr上,你可以使用这个:

$ saclst a f *2020-05*BHZ* 2> error.log

虽然 awk(你问的)有效,

sed -n 's/.*Error.*:/ /p' ip.txt

也可以。并且

grep Error ip.txt

所以,不要只关注使用 awk

如果你想清理 awk 代码(假设 +$2 是正确的),试试

saclst ... 2>&1 | [g/m/n]awk '(+<+_)*(NF=!_)'

我建议 + 的原因是,如果该值不“显示”为数字,则正在读取的输入会执行 string-based-comparison,从而导致以下情况无效像第 2 列中数字前面的感叹号 ! 这样的数据最终会使条件评估为真,即使它显然不是负数

  • !\x21
  • ASCII 0\x30

这就是它无意中通过过滤器的原因:

 echo '12 !232523435 2997 ' \
 \
 | mawk '<0'

 12 !232523435 2997 

现在这只是假设 OP 的原始逻辑检查 $2 是否为负数是准确的。

为了正确处理 ip.txt,我测试了另一个变体:

% < ip.txt [g/m/n]awk '/: .+: .+:/ && ($!_=$_=$NF)~_'

GS.GS043.2020-05-18T14:36.BHZ.sac

我创建了 ip.txt 的合成版本,大小为 8.27 GB。也许 grep 或 sed 更快,但我个人认为 awk 的过滤吞吐率 532 MB/s 应该足够了:

 pvE0 <  ip2.txt | mawk2 '/: .+: .+:/ && ($!_=$_=$NF)~_' | pvE9 | xxh128sum 

      in0: 8.27GiB 0:00:15 [ 532MiB/s] [ 532MiB/s]             
     out9:  938MiB 0:00:15 [59.0MiB/s] [59.0MiB/s] [        <=>  ]

e8626c6b7e7c90a5cb21bd00fee6ec41  stdin