Grab certain contents of a file

So I know tools exist for this problem because I’ve heard about them, but I don’t know what they are.

I want to do something like filter out all data but the usernames in /etc/passwd.

For example, I would want to grab user1, user2, and user3 from the following file. In this case, the logic could be “Grab text up to the first ‘:’ on each line of the file”.


The output would be:

Asked By: mouche


Every time you want to extract data from a tabular input, you should consider awk. It is available on virtually every Unix system, so it’s a good habit to take:

awk -F':' '{print $1}' /etc/passwd 
  • -F':': defines “:” as the column delimiter.
  • '{}': execute this instruction for each line.
  • print $1: print the first column to the screen.
Answered By: Matthew Brannigan

cut exists for exactly this purpose. The -d flag specifies the delimiter, and -f specifies which fields to output:

cut -d: -f1 /etc/passwd

The argument to -f can be something like 1,3 to show the first and third fields, or 1-3 to show the first three; there are also -b and -c flags to read bytes and characters instead of fields. If you need something more flexible, generally awk will do the trick (see Matthew’s answer)

Answered By: Michael Mrozek

Here’s a Perl one-liner:

perl -F/:/ -lane 'print $F[0]' /etc/passwd
Answered By: Zaid

Beneath perl and awk, there is a third tool for such jobs, which is sed:

sed 's/:.*//' FILE 

This is the substitution command: substitute from colon :, followed by a dot, which is a joker for characters of any kind, of any count (*), with nothing.

It is ‘s(ubstitute)/FROM/TO/’ with TO being empty, which means ‘delete everything from the first (since sed is by default greedy) colon (till end of line, since sed works well with entire lines).

Of course cut is a fine command as well, but I would say from a different family.

Answered By: user unknown

In your example, all 3 names are of the same length. In such cases – which might happen, but not so likely with /etc/passwd – you might use colrm too:

echo "user1:x:1:4
> user2:x:2:5
> user3:x:3:6" | colrm 6

or, of course

cat FILE | colrm 6 

(a rare case where useless use of cat doesn’t apply, because you can’t hand colrm a FILE to act on as parameter.)

Answered By: user unknown

Just for completeness, there is no need for external commands, the shell (Bourne shell or compatible) can handle it alone:

while IFS=':' read -r needed garbage; do echo "$needed"; done < input_file

Of course, this is probably the slowest of all possible solutions, so for huge files pick another.

Answered By: manatwork
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.