I am looking to automate something with a script in bash or python.

Let's say I have a config file from a device. A simple config.txt file. Content could be like this (actual file is much longer and has much more text):

> cat config.txt
> ASA Version 9.1(5) 
> !
> terminal width 511
> hostname confidential
> domain-name confidential
> enable password  encrypted
> passwd  encrypted
> names
> !
> interface GigabitEthernet0/0
>  nameif interconnection
>  security-level 50
>  ip address standby 
> !
> interface GigabitEthernet0/1
>  description Trunk
>  no nameif
>  no security-level
>  no ip address
> !
> interface GigabitEthernet0/1.4
>  description confidential
>  vlan 4
>  nameif vlan004_confidential
>  security-level 50
>  ip address 
> !
> object network confidential
>  host
> object network confidential2
>  host
> object network confidential3
>  host
>access-list vlan65_access_in extended permit object-group confidential any object-group confidential 
>access-list vlan65_access_in remark Allow ICMP OK-20131105
>access-list vlan65_access_in extended permit icmp any object vlan48-confidential 
>access-list vlan65_access_in remark Allow NTP OK-20131105
>access-list vlan65_access_in extended permit udp any object-group confidential eq ntp 
>access-list warehouse_access_in remark Access to confidential
>access-list warehouse_access_in extended permit object-group confidential any object-group confidential 
>access-list warehouse_access_in remark Access to DNS srvrs
>access-list warehouse_access_in extended permit ip any object-group DNS_Servers 
>access-list warehouse_access_in remark Allow acces to AD
>no pager
>logging enable
>logging timestamp
>logging standby
>logging list SysLogs message 304001
>logging list connections message 302013-302304
>logging list NewConnection message 302303
>logging list NewConnection message 302015
>logging list NewConnection message 302013
>logging list NewConnection message 303002
>logging list Dropped message 106001-106103
>logging list ConfigChange message 111008
>logging list ConfigChange message 111001
>logging list ConfigChange message 111010
>logging buffer-size 1048576
>logging monitor debugging
>logging buffered warnings
>access-group vlan4_access_in in interface vlan004_confidential1
>access-group vlan65_access_in in interface vlan065_confidential2
>access-group vlan66_access_in in interface vlan066_confidential3
>access-group vlan80_access_in in interface vlan080_confidential4
>service-policy global_policy global
>service-policy test interface interconnection
>service-policy imec_intranet_traffic-policy interface vlan065_confidential5
>service-policy imec_intranet_traffic-policy interface vlan066_confidential6
>service-policy imec_intranet_traffic-policy interface vlan080_confidential7
>service-policy imec_intranet_traffic-policy interface vlan082_confidential8
>service-policy imec_intranet_traffic-policy interface vlan083_confidential9
>: end

My second file is a list (list.txt). And the content and layout is something like this (in notepad++):


>username    full name                       employid  group           left comp on
>test16    confidential1                        00014241  zzzz1             19-08-2017
>test38    confidential2                        00014223  zzzz2             12-08-2017
>test47    confidential3                        00013986  zzzz3             06-07-2017
>test85    confidential4                        00013923  zzzz4             16-07-2017

Is it possible to run a script that takes every word in the "username" and "full name" column in the list.txt file and check if there is a match in the config.txt file? It would be great to have the output of the script in a third file that mentions what word (here username or full name) is found in the config.txt file and where.

Let's say I want to know if test38 is somewhere in the config.txt file? I now I can simply grep, but my list.txt file has around 100 users. I don't want to grep 100 times. On top of that, I'll get more lists in the future.

  • What is the format of each file? Could add an extract, of course without real names? – Toto Sep 1 '17 at 9:02
  • For the list I could use csv, xls, txt. The config output of the Cisco ASA is just a file on a linux box. – maxim Sep 1 '17 at 9:15
  • Let us continue this discussion in chat. – maxim Sep 1 '17 at 12:10
  • You could pass to grep -f a file with the words to search, could be grep -FnH -f <( sed -nr 's/^>([[:alnum:]]+) +([[:alnum:]]+).*/\1\n\2/p' list.txt ) config.txt. – Paulo Sep 4 '17 at 18:30

Here is a perl script that does the job, (as far as I understand):

use strict;
use warnings;

my $config  = 'config.txt';   # give the full path
my $list    = 'list.txt';     # give the full path
my $outfile = 'outfile.txt';  # give the full path

# read list file and store in a hash
open my $fhl, '<', $list or die "unable to open '$list': $!";
my %users;
while(my $line = <$fhl>) {
    next if $. < 3;     # skip first 2 lines (header)
    my ($user, $name) = split(/\s+/, $line);
    $users{$user} = $name if $user and $name;
close $fhl;

open my $fhc, '<', $config or die "unable to open '$config': $!";
open my $out, '>', $outfile or die "unable to open '$outfile': $!";
# read config line by line
while(my $line = <$fhc>) {
    # loop on all users
    while( my ($u,$n) = each(%users)) {
        # print outputfile if user found 
        print $out "$u:$n found line $.\n" if $line =~ /\b($u|$n)\b/;

outputfile for given example

test38:confidential2 found line 30
test47:confidential3 found line 32
| improve this answer | |
  • Many thanks. I'll make time today to test it, make changes if necessary and let you know the outcome. – maxim Sep 4 '17 at 8:22
  • Very nice! Works from first time. I will try to understand what you did here because I am not good at scripting and programming. Is it also possible to get rid of the empty lines ": found line x"? I have +7000 lines now. How could I make the script that it only returns the matches? Anyway this helps me already a lot. So thank you very much! – maxim Sep 4 '17 at 10:02
  • @maxim: You're welcome, glad it helps. Sorry, I don't get you about empty lines,the script print on outputfile only if there is a match. Do you means there are empty lines in list.txt ? – Toto Sep 4 '17 at 10:11
  • No empty lines in list.txt. But the outfile writes every line of my config.txt file as for example ": found line 7081". It starts at 1 and ends at 7114. The config.txt file counts 7114 lines too. Between these 7114 lines in the outfile I can see the matches like this: "schaba27:confidential found line 5319". – maxim Sep 4 '17 at 11:02
  • @maxim: Change $users{$user} = $name ; into $users{$user} = $name if $user and $name;, see my edit. – Toto Sep 4 '17 at 11:27

According to my personal understanding about your requestion, I use builtin command while and command awk to solve it.

directly output

awk 'NR>2{print $1,$2}' list.txt | while IFS=" " read -r username fullname; do awk -v name="${username}" 'BEGIN{OFS="|"}match($0,/'"${fullname}"'/){gsub(/>/,"",name);print name,NR,$0}' config.txt; done

write output to file output.txt

awk 'NR>2{print $1,$2}' list.txt | while IFS=" " read -r username fullname; do awk -v name="${username}" 'BEGIN{OFS="|"}match($0,/'"${fullname}"'/){gsub(/>/,"",name);print name,NR,$0>>"output.txt"}' config.txt; done

output format is

user name|line no.|match content

Result output

test16|64|>access-group vlan4_access_in in interface vlan004_confidential1
test38|30|> object network confidential2
test38|65|>access-group vlan65_access_in in interface vlan065_confidential2
test47|32|> object network confidential3
test47|66|>access-group vlan66_access_in in interface vlan066_confidential3
test85|67|>access-group vlan80_access_in in interface vlan080_confidential4
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.