grep模式从文件中排除负数

时间:2020-12-30 08:54:29

I have been struggling trying to come up with an easier answer to this problem. But still using grep.

我一直在努力寻找一个更简单的答案来解决这个问题。但仍然使用grep。

I want to grep out the positive (and negative numbers) of myfile.dat. Myfile.dat look like this:

我想提取myfile.dat的正数(和负数)。Myfile。dat看起来像这样:

-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.

不需要保留列格式。所以我使用了下面的grep模式。

Negative numbers:

负数:

grep -E -o [-][0-9]+.[0-9]+ myfile.dat

Positive numbers (here I have to pipe all numbers into another grep):

正数(这里我必须把所有的数字转换成另一个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?

问题来了!是否有一个grep模式允许我直接提取正数,而不使用第二个grep命令?

This is all about the pattern, not whether I could use another command.

这与模式有关,而不是我是否可以使用另一个命令。

5 个解决方案

#1


3  

Using grep -P you can do this to get all positive numbers:

使用grep -P可以得到所有正数:

 grep -oP '(?<!-)\b[0-9]+\.[0-9]+\b' file

#2


2  

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.

tr -d ' ' '只是从输出中删除任何初始空间,如果不需要,可以跳过它。

#3


1  

Can you use sed instead of grep? Remove negative numbers:

你能用sed代替grep吗?消除消极的数字:

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/^ //.

删除一个负号后面跟着数字和点s/-[0-9.]*// /g的每个序列。和美化删除任何领先的空间可能保持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.)

删除一个数字和点的线s / ^[0 - 9]* / /。替换空白,后面跟着数字和圆点,只有空白s[0-9]。* / / g。最后再美化,主要把多余的空格开始的时候行s / ^ * / /。(可能有一种更简单的方法,但目前还看不到。)

#4


1  

If you want to preserve the column format, you can use a BASH read loop.

如果希望保留列格式,可以使用BASH读取循环。

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

#5


1  

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.

好的,已经提供了sed, grep和pure shell的解决方案,我给awk一个。事实上,我没有得到提供的答案,当问题是关于计算的时候,为什么要使用一些不适合计算的工具。

 awk '{for (i=1;i<=NF;i++) if ($i>=0) print $i} ' file

#1


3  

Using grep -P you can do this to get all positive numbers:

使用grep -P可以得到所有正数:

 grep -oP '(?<!-)\b[0-9]+\.[0-9]+\b' file

#2


2  

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.

tr -d ' ' '只是从输出中删除任何初始空间,如果不需要,可以跳过它。

#3


1  

Can you use sed instead of grep? Remove negative numbers:

你能用sed代替grep吗?消除消极的数字:

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/^ //.

删除一个负号后面跟着数字和点s/-[0-9.]*// /g的每个序列。和美化删除任何领先的空间可能保持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.)

删除一个数字和点的线s / ^[0 - 9]* / /。替换空白,后面跟着数字和圆点,只有空白s[0-9]。* / / g。最后再美化,主要把多余的空格开始的时候行s / ^ * / /。(可能有一种更简单的方法,但目前还看不到。)

#4


1  

If you want to preserve the column format, you can use a BASH read loop.

如果希望保留列格式,可以使用BASH读取循环。

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

#5


1  

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.

好的,已经提供了sed, grep和pure shell的解决方案,我给awk一个。事实上,我没有得到提供的答案,当问题是关于计算的时候,为什么要使用一些不适合计算的工具。

 awk '{for (i=1;i<=NF;i++) if ($i>=0) print $i} ' file