Home > Enterprise >  File Filtering with awk with brackets
File Filtering with awk with brackets

Time:12-22

I am just using awk to filter some contents from the file in Linux which is simple and i am able to get what is needed but i little fail to understand the logic. I hope someone will make it clear for me and other like me.

1- File contents are like below ...

  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded
  check_ntlm_password:  authentication for user [cnf76628] -> [cnf76628] -> [cnf76628] succeeded

2- What I'm trying to do is to get user ID's which are within [] as follows.

# awk -F'[][]' '/authentication for user/{print $2}' test_file

So, what I'm failed to understand is why $2 is the User ID as its fifth column where it exits but it takes $2 though? Does it mean the string I'm looking like authentication for user is getting considered $1 as a starting point?.

Any clarity will be helpful.

CodePudding user response:

-F defines the field separators - by default spaces or tabs.

-F'[abc]' defines a or b or c as separators, and thus -F'[[]]' makes either [ or ] separate a field.

With that in mind, the second field comes between the first and second separators.

CodePudding user response:

Your field separator regex matches either [ or ], and each of the line ("records") above are actually split into seven fields (see enter image description here

When you use /authentication for user/ it checks for the presence of authentication for user anywhere on a line, i.e. in the $0 field. However, authentication for user is present in Field 1, so your understanding is right.

So, the consfusion comes from the fact that [][] splits the records/lines with single brackets, ] or [, into fields so the ID is not in the 5th field, but the second one. If you remove -F'[][]' the default separator would be used, whitespaces, and the ID would land in Field 5 then.

CodePudding user response:

The approach fails for obvious reasons since you're defining the separator, not the field.

Here's one way to get what you had in mind. It places the fields with a starting [ and a trailing ] at the end of the line which can be accessed with $(K 1), $(K 2) etc.

$ awk '/authentication for user/{ K=NF; x=NF; 
    for(i=1;i<=NF;i  ){ 
      if($i~/^\[/&&$i~/\]$/){ 
        x  ; gsub("\[|\]","",$i); $x=$i } } 
    print $(K 1),$(K 3) } END{ print "A full line:\n"$0 }' file
cnf76628_1 cnf76628_3
cnf76628_1 cnf76628_3
cnf76628_1 cnf76628_3
A full line:
check_ntlm_password: authentication for user cnf76628_1 -> cnf76628_2 -> cnf76628_3 succeeded cnf76628_1 cnf76628_2 cnf76628_3

Data

cat file
  check_ntlm_password:  authentication for user [cnf76628_1] -> [cnf76628_2] -> [cnf76628_3] succeeded
  check_ntlm_password:  authentication for user [cnf76628_1] -> [cnf76628_2] -> [cnf76628_3] succeeded
  check_ntlm_password:  authentication for user [cnf76628_1] -> [cnf76628_2] -> [cnf76628_3] succeeded
  • Related