Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

user1:x:1:4
user2:x:2:5
user3:x:3:6

The output would be:

user1
user2
user3
share|improve this question
add comment

6 Answers 6

up vote 19 down vote accepted

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)

share|improve this answer
    
Wow, that's pretty slick. Thanks. –  mouche Aug 30 '10 at 3:34
add comment

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.

share|improve this answer
add comment

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
user1
user2
user3

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

share|improve this answer
    
cat is still useless there: colrm 6 < FILE. –  manatwork Jun 28 '12 at 7:10
    
Well, yes, but not that useless, as in calling cat foo | grep bar. –  user unknown Jun 28 '12 at 9:50
add comment

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.

share|improve this answer
add comment

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.
share|improve this answer
3  
Random note: awk takes a filename, so you can skip the pipe and just do awk -F: '{print $1}' /etc/passwd –  Michael Mrozek Aug 30 '10 at 2:56
    
Works for me, thanks. –  mouche Aug 30 '10 at 3:36
    
I always seem to forget that awk takes a filename, I always seem to use it in a pipeline...something like sed | awk etc... –  Matthew Brannigan Aug 30 '10 at 14:39
    
almost everything that works with files take a filename (tr and at are a couple examples of the few things that don't). –  Dennis Williamson Aug 30 '10 at 22:04
add comment

Here's a Perl one-liner:

perl -F/:/ -lane 'print $F[0]' /etc/passwd
share|improve this answer
    
+1 Works for me. –  mouche Aug 31 '10 at 2:01
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.