Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I have a input file like

 foo xxx yyy zzz
 foo xxx yyy zzz
 foo xxx yyy zzz
 foo xxx yyy zzz
 bar xxx yyy zzz
 bar xxx yyy zzz
 foo xxx yyy zzz
 ..

How to split the input file by line, into foo.txt and bar.txt, depending on the existence of foo and bar at the beginning of the line?

share|improve this question

5 Answers 5

grep -E '^foo' input.txt > foo.txt
grep -E '^bar' input.txt > bar.txt

mbp-000234:~ dmourati$ cat foo.txt

foo xxx yyy zzz
foo xxx yyy zzz
foo xxx yyy zzz
foo xxx yyy zzz
foo xxx yyy zzz

mbp-000234:~ dmourati$ cat bar.txt

bar xxx yyy zzz
bar xxx yyy zzz
share|improve this answer
    
THis method definitely work, but it require two scan to the file.. –  Ryan Jun 15 at 8:39
grep ^foo input.txt > foo.txt
grep ^bar input.txt > bar.txt

^ will make sure you only match the beginning of the line, so it will work even if the rest of the line looks like:

foo xxx yyy zzz bar
share|improve this answer
awk '{ f = $1 ".txt"; print > f }' file
share|improve this answer
    
would you please elaborate how above script executes. –  ali786 Jun 14 at 4:47
    
For each line, set a variable f with the value of the first field concatenated with the string ".txt" (the awk concatenation "operator" is to put expressions side-by-side). Then print the file to the file named in the variable f. –  glenn jackman Jun 14 at 15:30

Try this code, and make any chages if need since i have not tried to run it.

awk '
    BEGIN { foo="foo.txt"; bar="bar.txt" }
    {if ($1 == "foo")
         $0 >> foo;
     else
             $0 >> bar;
    }' sourcefilename
share|improve this answer
    
-1: the variables foo and bar are empty. You need a string on the right-hand-side of the redirection. –  glenn jackman Jun 13 at 11:38
    
instead of -1 you might have edited it if you know the correct script, i have just given suggestion, i have not tried it. I already mention in my ans. –  ali786 Jun 13 at 11:45
    
well, fix it and I'll remove my downvote –  glenn jackman Jun 13 at 12:17
1  
My edit is awaiting review. However, and the OP will need to provide an opinion, if your code sees a line beginning with "qux", that line will be added to "bar.txt" -- I suspect the OP would prefer "qux.txt" –  glenn jackman Jun 13 at 14:43

You can also distribute the file stream with tee and then split in parallel:

<file tee >(grep '^foo' > foo.txt) >(grep '^bar' > bar.txt) > /dev/null

Result:

$ tail -n+1 foo.txt bar.txt
==> foo.txt <==
foo xxx yyy zzz
foo xxx yyy zzz
foo xxx yyy zzz
foo xxx yyy zzz
foo xxx yyy zzz

==> bar.txt <==
bar xxx yyy zzz
bar xxx yyy zzz
share|improve this answer
    
tail -n+1? That a pretty obscure way to say cat. –  glenn jackman Jun 13 at 14:45
1  
@glennjackman: it has the extra benefit of including the file names in the output. –  Thor Jun 13 at 14:59

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.