Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete all characters using sed except missing values

Tags:

sed

awk

I have a text file as below:

$cat text.txt

 An = 2, 3, 4, 5, 0.3
      3, 3, 4, 5, 0.5
      3, 4, 5, 6, -19
      4, 5, 5, 5, 10E+10

I would like to delete all the characters except the missing values like 10E+10

Desire output is

$Outfile.txt

2 3 3 4 0.3
3 3 4 5 0.5
4 4 5 5 -19
5 5 6 5 10E+10

My below script is deleting all the characters including E

$script.sh

sed 's/[A-Z]//g;s/=//g;s/}//g;s/[a-z]//g;s/,//g' text.txt
like image 777
Kay Avatar asked Aug 07 '26 20:08

Kay


2 Answers

Using any awk:

$ awk '
    {
        gsub(/,/," ")
        out = sep = ""
        for ( i=1; i<=NF; i++ ) {
            if ( $i == $i+0 ) {
                out = out sep $i
                sep = OFS
            }
        }
        print out
    }
' text.txt
2 3 4 5 0.3
3 3 4 5 0.5
3 4 5 6 -19
4 5 5 5 10E+10

That if ( $i == $i+0 ) is the idiomatic way to test for a value being a number (which I think is what you're asking for) since only a numeric value equals itself before and after adding 0 to it.

like image 55
Ed Morton Avatar answered Aug 10 '26 06:08

Ed Morton


tr -d '[A-DF-Za-z,=]' < text.txt | sed 's/^  *//'

produces

2 3 4 5 0.3
3 3 4 5 0.5
3 4 5 6 -19
4 5 5 5 10E+10

You can get similar results deleting character ranges with sed, and have a 2nd pass (as above) to remove the leading spaces.

sed 's/[A-DF-Za-z,=][A-DF-Za-z,=]*//g;s/^  *//'

The character range [A-DF-Za-z,=] matches any alpha character except E as well as , and =. If we just put * after it immediately we'd be saying zero or more of [A-D...], so we need to repeat the range so we match at least one of [A-D...] and then zero-or-more of the preceding. Using g of course globalizes the substitution per line.

We anchor the 2nd substitution at the front of the line with /^ and again, we need 2 space chars so that the * zero-or-more token will require at least one space at the front of the line to match.

You might want to use [A-DF-Za-df-z,=] as your range to allow for the possibility that some software will output lower case chars as part of the exponent.

There are of course possible inputs that will cause this to fail, but if your data source is well organized and consistent then this can work.

There are also home-brew awk functions that can determine isNum() and that would probably be more bullet proof than above. But that,... is a separate question (-;

like image 33
shellter Avatar answered Aug 10 '26 05:08

shellter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!