1

我想在目录中的每个文件上运行 AWK 脚本,但 AWK 命令必须仅在该文件中运行 - 也就是说,它在定义的 RS 之间搜索并返回它应该返回的内容,但我需要它在它停止时停止到达一个文件的结尾,然后在下一个文件的开头重新开始。

我有这个运行,它分别适用于每个文件:

awk '!/value1|value2/ && NF {print FILENAME " - " RS,$1}' RS="value" file1 > result.txt

但是输出不正确,例如,将其应用于目录中的每个文件时

find . -type f | awk ... file1 > result.txt

我如何让它单独查看每个文件,但将结果附加到同一个文件中?不幸的是,我不知道。我想这是通过将每个文件添加到一个变量中并让 AWK 查看它,但我不知道该怎么做。

文件文件1:

interface Vlan3990
 ip address 172.17.226.23 255.255.255.254

文件文件2:

version 12.2
ip tacacs source-interface Loopback99
ip vrf test
 description xx
interface Loopback99
 description Management Loopback
interface Loopback100
 shutdown

输出

find . -type f | xargs awk '!/description|shutdown/ && NF {print FILENAME " - " RS,$1}' RS="interface" | more
./file1 - interface Vlan3990
./file2 - interface version

我不确定输出“接口版本”来自哪里......

4

2 回答 2

9

仅针对当前目录:

for file in *
do awk ... "$file"
done > result.txt

如果需要递归到子目录:

find . -type f -exec awk ... {} ; > result.txt

在这两种情况下,您可能应该放在result.txt不同的目录中。否则,它将被匹配并用作输入文件。或者使用只匹配所需文件且不匹配的通配符result.txt

于 2013-10-21T15:42:17.253 回答
1

试试这个,给定您发布的 2 个输入文件:

$ gawk '
    function prtName() {
        if (name)
            print FILENAME, name
        name=""
    }
    /^interface/                { prtName(); name=$0 }
    /^ (description|shutdown)/  { name="" }
    ENDFILE                     { prtName() }
' file1 file2
file1 interface Vlan3990

那是你要找的吗?请注意,它是 gawk 特定的(ENDFILE

$ awk '
    function prtName() {
        if (name)
            print filename, name
        name=""
    }
    FNR==1                      { prtName(); filename=FILENAME }
    /^interface/                { prtName(); name=$0 }
    /^ (description|shutdown)/  { name="" }
    END                         { prtName() }
' file1 file2
file1 interface Vlan3990
于 2013-10-21T16:04:04.747 回答