マイナス記号を維持しながら特定の列の数値を削除しますか?


9

次のデータフレームが水平方向と垂直方向に無期限に続き、奇数列にのみ負の数が表示されます。

-1  2  3  4 -5  9
 2  3 -4  5 -6  11

そして、2番目、4番目、6番目の完全な列(またはすべての偶数列)と、1番目、3番目、および5番目(またはすべての奇数列)からのみマイナス記号が必要なので、これを取得します。

- 2   4 - 9
  3 - 5 - 11

そして最終的にこれで終わります:

-2  4 -9
 3 -5 -11

したがって、変更されていない偶数列と奇数列の値が必要です。負の値がある場合は-を保持し、正の値がある場合は破棄します。

これをawk / sedで行う方法はありますか?

これは私が得る限り遠いです:

awk '{ for (i=2;i<=NF;i+=2) $i="" }1' FILE.txt | sed 's/[0-9,.]*//g' 

データフレームが無期限に続くと言うとき、それは水平または垂直を意味しますか?実際にはいくつの列がありますか?
terdon

どちらも。私のテストデータは3行x 3列ですが、実際のデータにはさまざまな数があります。たとえば、最大40行40列です。
Asfound

回答:


2

これが1つの方法です。

$ awk '{for(i=1;i<=NF;i+=2){if($i<0){$i="-"}else{$i="";} }};1' file |
     sed 's/- */-/g; s/  */ /g'
-2 4 -9
 3 -5 -11

awkこのスクリプトは、すべての奇数列の上に行くとにその値を設定し-、彼らは否定されない場合は、空の場合。次に、は、sedaに続くスペースをすべて削除してから、-連続する複数のスペースを1つのスペースに置き換えます。これは、一部のフィールドに2つ以上の文字があり、他のフィールドに1つあるため、配置が壊れることを意味することに注意してください。フィールドを使用している場合は問題になりません。見栄えが悪いだけです。


4

sed道:

sed -E '
    s/^(([ \t]*-?[ \t]*[0-9.]+[ \t]+[0-9.]+)*)[ \t]+-?[ \t]*[0-9.]+$/\1/;
    s/[0-9.]+[ \t]+([0-9.]+)/\1/g'

出力:

-2  4 -9
 3 -5 -11

列の数が奇数の場合、最初の式は後続の列を削除します。これは<number> <number>、最初の数が負になる可能性がある0以上のペアを探すことによって行われます。

編集:sed @mikeservに触発された短いソリューション:

sed -E '
    s/[0-9.]+[ \t]*([0-9.]*)/\1/g;
    s/[- \t]*$//'

同じことperl

perl -lpe 's/^((\s*-?\s*[\d.]+\s*[\d.]+)*)\s+-?\s*[\d.]+$/$1/o; s/[\d.]+\s+([\d.]+)/$1/g'

別の方法perl(おそらく最もクリーンな方法):

perl -lpe '$a = 1; s/([\d.]+\s*)/$a++ % 2 ? "" : $1/eg; s/[-\s]*$//o'

スクリプトに小数点を追加する限り、これは実際のデータで問題なく機能します。ありがとう!
Asfound

@Asfound OK、小数点もサポートするように回答を編集しました。
lcd047

しばらくお待ちください。最後の(奇数)フィールドとして負の値がある場合、これは失敗します。
terdon

@terdon奇数の列がある場合、失敗します。しかし、正確に6列、または「無限に多数」であり、「無限に多数」は奇数ではありません。:)
lcd047 2015年

OP 、「最大40列」が存在する可能性があると述べました:(
terdon

3

perl1:

$ perl -anle 'BEGIN{$,=" "}
  print map{$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"}grep{!($_%2)}0..$#F' file
-2  4 -9
 3 -5 -11
  • -an入力を@F配列に分割
  • BEGIN{$,=" "} 出力フィールドセパレータをスペースに設定します
  • grep{!($_%2)}0..$#F@F奇数要素のインデックスである配列内のすべての偶数インデックスを取得します
  • map{$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"}奇数の要素がで始まるかどうかを確認し--次の偶数の要素に追加するか、スペースを追加します

3

@terdonの答えとして、sedなし:

awk '{ for(i=1;i<=NF;i+=2){
         if ($i<0) $(i+1)*=-1;
         $i = "";
       }
       print
     }'

3

pythonソリューション

python -c 'from __future__ import print_function; 
import sys, math;
for line in sys.stdin:
  x = [int(y) for y in line.split()]
  print(*[int(math.copysign(b, a)) for a, b in zip(x[::2], x[1::2])], sep=" ")
' <file

2

単純な数学ベースのawkソリューション:

$ cat <<M | awk '{for(i=2;i<=NF;i+=2){printf "%4s",($(i-1)<0?-1:1)*$i}print ""}'
-1  2  3  4 -5  9
2  3.2 -4  5 -6
M

  -2   4  -9
 3.2  -5
  • 2番目のi=2フィールド(i<=NF)から最後のフィールド()までループします。
  • 前のフィールド($(i-1))に-1または1を掛けます。
  • 出力を適切にフォーマットし(printf "%4s")、末尾の改行を出力します(print "")。

唯一の注意点は、奇数の列がある場合、最後のフィールドには何も表示されないことです。これがあなたの期待するものであることを願っています。どうやらこれはあなたが期待するものです。:)

(10進値を処理するように編集され、2つの文字を保存しながらループ条件を質問に合わせて調整します。)


1

ネガを完全に忘れる必要があります-除外してください。左から右へ、2つのフィールドを統合したいとします。とても簡単です。

sed '   s/ *\(.*\)/\1 /
        s/\([0-9]*  *\)\{2\}/\1/g
        s/[ -]*$//
' <<\IN
-1  2  3  4 -5  9
 2  3 -4  5 -6  11
IN
-2  4 -9
3 -5 -11

符号への参照をまったく回避していることに注意してください。入力が処理されるとき、オートマトンはスペースまたは数値のみを受け入れます。これは、オートマトンが何も理解しないためです。それ以外はすべて完全に無視され、そのまま残ります。

あなたが指定した場合\{の数値繰り返し間隔\}について\(部分式を\)、その式の最後の発生がある\1バック参照します。したがって、繰り返しの間隔を簡単に絞ったり、切り詰めたりすることができます。また、記号の後ろの繰り返しを絞り込んでいるため(1つある場合)、そのパターンの2番目の出現は、最初のパターンの前に使用されていたすべての記号の後に続きます。

上記の動作は、すべての BRE準拠アプリケーションに対してPOSIXによって指定されていますが、sed正しく動作するものはほとんどありません。GNU sedはそうします。

最後に、スペースはパターンの発生を規則的にするためのものです。

もちろん、これはあなたのために働くことは決してありません。または、おそらくより正確には、常に機能しますが、結果は返されません。パターンが不明確な場合はどうすればよいですか?


これは、フィールドの数が偶数の場合にのみ機能します。
terdon

@terdon-いいえ-それは何でも機能します。
mikeserv 2015年

いいえ、奇数のフィールドで試してください。最後のものは印刷されますが、印刷されるべきではありません。
terdon

@terdon-なぜそれはいけないのですか?キャンセルするための次のフィールドはありませんか?質問者は、奇数列とそれに続く偶数列を削除したいと述べています。最後の列の後には偶数列が続きません-必要なことを正確に実行し、できるだけ削除しません。一部のデータが送信されると想定することは、私の考えでは悪い習慣です。
mikeserv 2015年

いいえ、そうではありません。「だから、変更されていない偶数列と奇数列の値が必要です。負の値がある場合は-を保持し、正の値がある場合は破棄してください。」奇妙なフィールドは決して印刷すべきではありません。それらが与えるべき唯一の情報は、それらが否定的であったかどうかです。Yoursは正の奇数フィールドを出力します。
terdon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.