1

The problem I am working through is that I have a file that will contain fields delimited by a "|" and the file is sorted based on one of those fields. What I have been trying to come up with is a way to grab lines based on a range of a certain field.

an example:

Sample input would be something like this where it is sorted based on the 2nd field. So they are listed in alphabetical order

1234|abcd|3fgbe32
1234|abce|5fasdf3
5678|abcf|t438fjd
9876|abcg|57fshde

The range I want to get would then be "we want all records that fall in the range of abcd - abcf to be recorded into a different file. And the records remaining would be:

1234|abcd|3fgbe32
1234|abce|5fasdf33
5678|abcf|t438fjd

When I started I think I approached this in the wrong way. I was looping through each line and then trying to check the line against a regular expression to see if I wanted the line or not. But would there be a better way of doing this using awk and grep?

3

all records that fall in the range of abcd - abcf

Simple awk solution:

awk -F'|' '$2~/^abc[d-f]$/' file

The output:

1234|abcd|3fgbe32
1234|abce|5fasdf3
5678|abcf|t438fjd
0

Another solution :

awk -F'|' '{if ($2 == "abcd") { l=1} else if ($2 == "abcg") { l=0} }l' file 
0

A sed solution.

To delete the lines before the first in the range:

cat file | sed '/abcd/Q'

To delete the lines after the last in range:

cat file | sed -n '/abcf/,$p'

   -n : don't print non-matches
   ,$ : first match to end of file
   p  : print

Putting together:

cat file | sed '/abcd/Q | sed -n '/abcf/,$p'

The patterns will match any field in the line, so you would need a better pattern to match only the second field:

cat file | sed -r -n '/^[^\|]+\|abcd/,$p' | sed -r '/^[^\|]+\|abce/Q'

The very simple range using sed would be:

cat file | sed -n '/abc[def]/p'
0

records in the range of abcd - abcf using grep:

grep -E '^[^\|]+\|abc[d-f]\|'
0

All-in-one sed solution, writing the range from abcd to abcf to a file called other, while remaining lines are passed to stdout. So you don't have to go through the file twice.

sed -e '/|abcd|/,/|abcf|/{wother' -e 'd;}'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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