awk 匹配参数上方的所有行

awk 匹配参数上方的所有行

我有一个名为 test.out 的文件,其中包含以下几行:

-rw-rw----    1 informix informix    9117025 Jan 21 05:22 shop4_0_Log0000331875.Z
-rw-rw----    1 informix informix    8897981 Jan 21 05:24 shop4_0_Log0000331876.Z
-rw-rw----    1 informix informix    9325351 Jan 21 05:31 shop4_0_Log0000331877.Z
-rw-rw----    1 informix informix    9645109 Jan 21 05:34 shop4_0_Log0000331878.Z
-rw-rw----    1 informix informix    9950581 Jan 21 05:40 shop4_0_Log0000331879.Z
-rw-rw----    1 informix informix   10655940 Jan 21 05:59 shop4_0_Log0000331880.Z
-rw-rw----    1 informix informix   10832325 Jan 21 06:39 shop4_0_Log0000331881.Z
-rw-rw----    1 informix informix    8521443 Jan 21 07:42 shop4_0_Log0000331882.Z
-rw-rw----    1 informix informix   10283566 Jan 21 08:02 shop4_0_Log0000331883.Z
-rw-rw----    1 informix informix   10633957 Jan 21 08:51 shop4_0_Log0000331884.Z

我想打印 grep value 331881 参数上方的所有行:

我想要的结果必须如下所示:

-rw-rw----    1 informix informix    9117025 Jan 21 05:22 shop4_0_Log0000331875.Z
-rw-rw----    1 informix informix    8897981 Jan 21 05:24 shop4_0_Log0000331876.Z
-rw-rw----    1 informix informix    9325351 Jan 21 05:31 shop4_0_Log0000331877.Z
-rw-rw----    1 informix informix    9645109 Jan 21 05:34 shop4_0_Log0000331878.Z
-rw-rw----    1 informix informix    9950581 Jan 21 05:40 shop4_0_Log0000331879.Z
-rw-rw----    1 informix informix   10655940 Jan 21 05:59 shop4_0_Log0000331880.Z

使用下面的命令我可以指定要打印多少行:

grep -n 331881 test.out | cut -d':' -f1 |  xargs  -n1 -I % awk "NR<=%+0 && NR>=%-1" test.out | sed '$d'

上面的命令只会打印指定的行数,在本例中为 1 行,但我想更改上面的内容以打印 grep 行上方的所有内容。我正在努力寻找解决问题的方法或更简单的方法。

答案1

假设您位于包含列出的文件的目录中,使用zsh

ls -ld shop4_0_Log<331882->.Z

<331882->一个zsh特定的 glob,匹配 331882 或更大的整数。

使用其他一些外壳:

for name in shop4_0_Log*.Z; do
    number=${name#shop4_0_Log}
    number=${number%.Z}

    if [ "$number" -ge 331882 ]; then
        ls -ld "$name"
    fi
done

shop4_0_Log在这里,我们循环遍历以 开头和结尾的名称.Z。对于每个这样的名称,我们挑选出文件名的整数部分,如果它是 331882 或更大,我们就调用ls -ld该名称。

如果前导零导致 shell 将某些数字解释为八进制(在我的测试中没有),则10#$number在测试中使用强制数字被解释为十进制整数(这是由kshandbash和一些支持的)其他贝壳)。

这两种变体都不依赖于包含某些输出的文本文件的存在ls

有关的:

答案2

我认为你可以直接使用 awk :

awk '/331881/ { exit } 1' test.out

这将打印所有行,但对于匹配的行331881,退出。

答案3

另一个好的工具是sed

sed -n '/shop4_0_Log0000331881\.Z$/q;p' test.out

答案4

j=`awk '/331881/{print NR}' file`

awk -v j="$j" '{a[++i]=$0}/331881/{for(x=NR-j;x<NR;x++)print a[x]}' file

输出

-rw-rw----    1 informix informix    9117025 Jan 21 05:22 shop4_0_Log0000331875.Z
-rw-rw----    1 informix informix    8897981 Jan 21 05:24 shop4_0_Log0000331876.Z
-rw-rw----    1 informix informix    9325351 Jan 21 05:31 shop4_0_Log0000331877.Z
-rw-rw----    1 informix informix    9645109 Jan 21 05:34 shop4_0_Log0000331878.Z
-rw-rw----    1 informix informix    9950581 Jan 21 05:40 shop4_0_Log0000331879.Z
-rw-rw----    1 informix informix   10655940 Jan 21 05:59 shop4_0_Log0000331880.Z

相关内容