0

I have a file which is like this

user:[dgalanos] rid:[0xa35]
user:[roleary] rid:[0xa36]
user:[smorgan] rid:[0xa37]

How can i print only the usernames like this

dgalanos
roleary
smorgan

I tried

cat users.txt | awk -F  ':' '{print $2 > "users3.out"}'

But it did not give me the correct result i expected.

1
  • don't use awk redirection in awk '{print $2 > "users3.out"}' input when you don't needed and you actually wanted a shell redirection awk '{print $2}' input > users3.out . Commented Feb 15, 2022 at 7:47

2 Answers 2

1

If you set a colon as your field separator, the line

user:[dgalanos] rid:[0xa35]

will be split to

user
[dgalanos] rid
[0xa35]

I guess you want to split at either colon or space, then remove the brackets:

Also, awk defaults to read from a file, no need for cat:

awk -F  '[: ]' '{gsub(/[][]/,"",$2); print $2}' users.txt > users3.out

Or you use the brackets as field separator:

awk -F  '[][]' '{print $2}' users.txt > users3.out

Anyways, for such task, I'd prefer grep:

grep -Po 'user:\[\K[^]]*' users.txt > users3.out
0

The most simple way is to modify your command as follows:

awk -F '[' '{print $2}' users.txt | awk -F ']' '{print $1}' > users3.out

  • I'm using two piped awk to catch at first what is after the [ and then what is after the ]. The delimiter are you interested in is not the semiclon, but the brackets.
  • Piping | means that the output of the first command is used as input of the second command. The second awk does not work if you use it alone, but it gets some sense only if you pipe it to the first command.
  • When piping, you don't have to repeat the input file: for this reason in the second awk there is no repetition of the input file users.txt. If you are curious to use the second awk alone, write: awk -F ']' '{print $1}' users.txt
  • You don't need to redirect cat output to awk because awk can accept files as input
  • Your redirection to an output file must not be inside the awk command, but at the end of the full command.

If you want to see the results in the terminal but not in a file, you can remove the part from >

There is a more elegant way to get the data without piping two awk commands but defining the two brackets as delimiters:

awk -F '[][]' '{print $2}' users.txt > users3.out

2
  • The command give desired result. However can you explain why the second print command did not print anything. awk -F '[' '{print $2}' users.txt | awk -F ']' '{print $1}' . Is it something like AND statement. it prints only if both conditions before/after the pipe satisfied.
    – tcprks
    Commented Feb 14, 2022 at 10:31
  • check my edited answer, it should clear your doubts. Commented Feb 14, 2022 at 10:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .