1

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?

5 Answers 5

4
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
1
  • THis method definitely work, but it require two scan to the file..
    – Ryan
    Jun 15, 2014 at 8:39
1
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
1
awk '{ f = $1 ".txt"; print > f }' file
2
  • would you please elaborate how above script executes.
    – smali
    Jun 14, 2014 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. Jun 14, 2014 at 15:30
1

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
4
  • -1: the variables foo and bar are empty. You need a string on the right-hand-side of the redirection. Jun 13, 2014 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.
    – smali
    Jun 13, 2014 at 11:45
  • well, fix it and I'll remove my downvote Jun 13, 2014 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" Jun 13, 2014 at 14:43
0

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
2
  • tail -n+1? That a pretty obscure way to say cat. Jun 13, 2014 at 14:45
  • 1
    @glennjackman: it has the extra benefit of including the file names in the output.
    – Thor
    Jun 13, 2014 at 14:59

You must log in to answer this question.

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