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