Reputation: 51
I have been struggling trying to come up with an easier answer to this problem. But still using grep.
I want to grep out the positive (and negative numbers) of myfile.dat. Myfile.dat look like this:
-1.4987 4.1354 -8.1235
4.2322 -0.9842 -2.6845
3.6845 1.5132 -2.8452
0.0122 9.3542 -1.2354
-7.2127 -1.1253 -4.3967
0.3535 7.2416 -3.1277
No need to retain column format. So I have used the following grep patterns.
Negative numbers:
grep -E -o [-][0-9]+.[0-9]+ myfile.dat
Positive numbers (here I have to pipe all numbers into another grep):
grep -Eo [-]\?[0-9]+.[0-9]+ myfile.dat | grep -v [-]
Here comes the question! Is there a grep pattern that allows me to extract positive numbers directly, without the use of a second grep command?
This is all about the pattern, not whether I could use another command.
Upvotes: 5
Views: 4548
Reputation: 45333
Ok, solution with sed, grep and pure shell have been provided, I give the awk one. In fact, I didn't get the provided answers, when the problem is regarding calculation, why use some tools which are not good for calculations.
awk '{for (i=1;i<=NF;i++) if ($i>=0) print $i} ' file
Upvotes: 1
Reputation: 3646
If you want to preserve the column format, you can use a BASH read
loop.
Loop through an array of each line to check and unset each element that is negative.
while read -a n; do
for i in ${!n[@]}; do
if [[ ${n[$i]} =~ ^- ]]; then
unset n[$i]
fi
done
if [[ -n $n ]]; then
echo ${n[@]}
fi
done < myfile.dat
Upvotes: 1
Reputation: 3247
Can you use sed instead of grep? Remove negative numbers:
sed "s/-[0-9.]*//g; s/^ //" myfile.dat
Remove each sequence of a minus sign followed by digits and dots s/-[0-9.]*//g
.
And to beautify remove any leading spaces which may remain s/^ //
.
Keeping only the positive numbers is a bit more tricky.
sed "s/^[0-9.]*//; s/ [0-9.]*/ /g; s/^ *//" myfile.dat
Remove a digits and dots at the start of the line s/^[0-9.]*//
.
Replace a blank, followed by digits and dots with just the blank s [0-9.]*/ /g
. And finally the beautification again, to remove any remaining leading blanks at the start of the line s/^ *//
.
(Possibly there is a simpler way for this, but can't see it at the moment.)
Upvotes: 1
Reputation: 4494
You could match on beginning-of-line or space before digits:
$ grep -oE '(^| )[0-9]+\.[0-9]+' Myfile.dat | tr -d ' '
4.1354
4.2322
3.6845
1.5132
0.0122
9.3542
0.3535
7.2416
tr -d ' '
just removes any initial spaces from the output, you can skip it if not needed.
Upvotes: 2
Reputation: 786091
Using grep -P
you can do this to get all positive numbers:
grep -oP '(?<!-)\b[0-9]+\.[0-9]+\b' file
Upvotes: 3