Registered User
Registered User

Reputation: 265

Use sed to print matching lines

Sample data in a stackoverflow.csv file I have:

foo
foo
foo
foo
bar
bar
bar
bar
baz
baz
baz
baz

I know with sed -n /foo/p stackoverflow.csv > foo.csv

I'll get all records matching foo directed to that file, but I don't want to specify the matching pattern on the cli, I'd rather put it in a script and have all records (foo, bar and baz) sent to their own file.

Basically this in a script:

sed -n /foo/p stackoverflow.csv > foo.csv
sed -n /bar/p stackoverflow.csv > bar.csv
sed -n /baz/p stackoverflow.csv > baz.csv

Like this:

#!/bin/sh
sleep 2
sed -n /foo/p > foo.csv
sed -n /bar/p > bar.csv
sed -n /baz/p > baz.csv

This creates the files but they're all empty. Also, if the script were to have just one print statement, it works.

Any input?

Upvotes: 2

Views: 10683

Answers (3)

tripleee
tripleee

Reputation: 189397

The w command in sed allows you to write to a named file.

sed -n -e '/foo/wfoo.csv' -e '/bar/wbar.csv' \
    -e '/baz/wbaz.csv' stackoverflow.csv

Not all sed dialects accept multiple -e arguments; a multi-line string with the commands separated by newlines may be the most portable solution.

sed -n '/foo/wfoo.csv
    /bar/wbar.csv
    /baz/wbaz.csv' stackoverflow.csv

This examines the input file just once, and writes out the matching lines as it proceeds through the file.

To create a script which accepts one or more file names as arguments, replace the hard-coded file name with "$@".

#!/bin/sh
sed -n ... "$@"

Upvotes: 0

Amit
Amit

Reputation: 20456

You missed the input filename

#!/bin/sh
sleep 2
sed -n /foo/p stackoverflow.csv > foo.csv
sed -n /bar/p stackoverflow.csv > bar.csv
sed -n /baz/p stackoverflow.csv > baz.csv

You can provide input file as an argument to your script, in that case change the script to read an argument and pass it to the sed command. Run the script like this: ./script.sh input_filename, where you can specify different input files as argument.

#!/bin/sh

file=${1}

sed -n /foo/p ${file} > foo.csv
sed -n /bar/p ${file} > bar.csv
sed -n /baz/p ${file} > baz.csv

Upvotes: 5

Ben Whaley
Ben Whaley

Reputation: 34416

Here's a solution with grep in a loop where you don't need to provideeach term in advance. Assuming a bash shell:

for i in $(sort stackoverflow.csv | uniq); do grep $i testfile > $i; done

Upvotes: 0

Related Questions