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 
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
