奇数列にのみ負数を使用して、水平方向と垂直方向に無限に続く次のデータフレームがあります。
-1 2 3 4 -5 9
2 3 -4 5 -6 11
私は2番目、4番目、6番目の全列(またはすべての偶数列)が必要で、マイナス記号は最初、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'
答え1
方法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>
最初の数字が負の数である可能性があるゼロ以上のペアを見つけてこれを実行します。
編集する: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'
答え2
一つずつperl
:
$ 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
}'
答え4
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
はすべての奇数列を繰り返し、その-
値が負の場合は値を設定し、それ以外の場合はnullに設定します。次に、sed
aの後ろのすべてのスペースを削除し、-
複数の連続したスペースを単一のスペースに置き換えます。これは、一部のフィールドに複数の文字が含まれ、他のフィールドに1つの文字が含まれているため、ソートが壊れていることを意味します。問題にならないフィールドを使用した場合は、表示には悪いだけです。