Reputation: 457
I want to run an AWK script on each file in a directory, but the AWK command must run only within that file - that is, it searches between a defined RS and returns what it is supposed to, but I need it to stop when it reaches the end of one file, and begin again at the start of the next file.
I have this running which works on each file individually:
awk '!/value1|value2/ && NF {print FILENAME " - " RS,$1}' RS="value" file1 > result.txt
But the output isn't correct, say, when applying it to each file in a directory using
find . -type f | awk ... file1 > result.txt
How would I get it to look at each file individually, but append the results into the same file? I have no idea unfortunately. I guess it's by adding each file into a variable and having AWK look at that, but I am not sure how to do it.
interface Vlan3990
ip address 172.17.226.23 255.255.255.254
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
I am not sure where the output 'interface version' is coming from...
Upvotes: 1
Views: 16813
Reputation: 204005
Try this, given your 2 posted input files:
$ gawk '
function prtName() {
if (name)
print FILENAME, name
name=""
}
/^interface/ { prtName(); name=$0 }
/^ (description|shutdown)/ { name="" }
ENDFILE { prtName() }
' file1 file2
file1 interface Vlan3990
Is that what you're looking for? Note that it's gawk-specific (courtesy of ENDFILE
) which I assume is fine since the sample command you posted is also gawk-specific but if that's an issue just add a test for FNR==1 and change ENDFILE to END:
$ 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
Upvotes: 2
Reputation: 781741
For just the current directory:
for file in *
do awk ... "$file"
done > result.txt
If you need to recurse into subdirectories:
find . -type f -exec awk ... {} ; > result.txt
In both cases, you should probably put result.txt
in a different directory. Otherwise, it will be matched and used as an input file. Or use a wildcard that only matches the desired files, and doesn't match result.txt
.
Upvotes: 9