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.

I'm trying to use the sed command to search a file for all entries 10000 and under but I think this incomplete sed search string might be for entries 10000 and over:

sed -n "/[0-9][0-9][0-9][0-9][0-9]/ q" logfile
share|improve this question

4 Answers 4

You can also do it using the following method:

$ sed -n "/^[0-9]\{0,4\}$\|10000/p" logfile

Example

Say I had a sample file, logfile, like so:

$ seq 9900 10050  | sed 's/$/ /' > logfile

This results in the file logfile looking like this:

$ head -5 logfile 
9900
9901
9902
9903
9904

$ tail -5 logfile 
10046
10047
10048
10049
10050

There's a trailing space after each of these lines thanks to the sed 's/$/ /' line above when we created the sample file.

Now when we run the above sed command:

$ sed -n "/^[0-9]\{1,4\}[^0-9]\|10000/p" logfile  | tail -5
9996 
9997 
9998 
9999 
10000 

We get everything up to 10000, and nothing more.

How it works

The above sed works by finding lines that begin with a range of digits, 0-9, ranging in length between 1 up to 4. The notation to sed, "/^[0-9]\{1,4\}[^0-9] performs this part. The notation [^0-9] at the end there says characters that are not a 0-9. This stops sed from matching substrings in numbers that are longer.

The \|10000 matches 10000 since it's a bit of a unique pattern compared to the rest of the strings up to it. The trailing p tells sed to print the results.

Using grep as an alternative

The use of sed isn't really the right tool for searching. You're likely better off to use grep for this instead.

$ grep "\b\([0-9]\{1,4\}\|10000\)\b" logfile | head -5
9900 
9901 
9902 
9903 
9904 

$ grep "\b\([0-9]\{1,4\}\|10000\)\b" logfile | tail -5
9996 
9997 
9998 
9999 
10000 

The above will find all lines that contain a string of digits that are 10000 or below. The \b denotes a border either before or after the string.

share|improve this answer

Perl can make this easier and more readable:

perl -nE 'say for grep { $_ <= 10_000 } /([0-9]+)/g' your_file
share|improve this answer
sed '/[0-9]/!d;/10000/q' <log.file

As long as the entries are in sequential order, you only need to specify that the line contain a number !else delete it. And when you get to line 10000 you quit. But 10000 is still printed - it will be the last line printed.

This would also be a lot better if you could anchor it - maybe to the beginning of the line like:

sed '/^[0-9]/!d;/^10000/q' <log.file

Which would be a surer - and faster - thing.

But, as slm points out, grep would be faster.

share|improve this answer
sed -nr "/0|[1-9][0-9]?[0-9]?[0-9]?[0-9]?/p" logfile
share|improve this answer

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.