2つのデータファイルがあり、one.txt
Linuxtwo.txt
システムにあります。すべての正の値を負にone.txt
変換するか、その逆に変換したいのですが、two.txt
最初の列でのみ可能です。データにはゼロも含まれています。
one.txt
次のようになります。
10 35.74
8 35.74
6 35.74
4 35.74
2 35.74
0 35.74
two.txt
このように
-20 35.74
-18 35.74
-16 35.74
-14 35.74
-12 35.74
-0 35.74
one.txt
私はこれを次のように変更したいと思います:
-10 35.74
-8 35.74
-6 35.74
-4 35.74
-2 35.74
-0 35.74
同様に、負の値をすべて正の値に変更したいと思います。two.txt
私はそれを試しましたが、awk '$1 *= -1' file.txt
ゼロをめちゃくちゃにしました。
この2つの問題は、2つの異なるプロセスで実行する必要があります。だから私は1つのステップで解決するのではなく、各問題に対して2つの異なるソリューション/コードを使用することを好みます。
答え1
試みを少し変えると効果があります。
awk '{ $1 *= -1 } 1' file.txt
問題は、awk '$1 *= -1'
これが$1 *= -1
条件として扱われることです。その効果は適用されますが条件になるため、結果がゼロでない場合にのみ処理された行が出力されます。
中かっこを追加すると、すべての行に乗算が適用され、それ自体ですべての行1
が印刷されます。空行を変更したくない場合は、乗算に条件を追加できます。
awk 'NF { $1 *= -1 } 1' file.txt
Gawk1を使用している場合は、最初の列を変更する前に数字であることを確認できます。
awk 'typeof($1) == "strnum" { $1 *= -1 } 1' file.txt
POSIXLY_CORRECT
1. 環境に変数がありません。
答え2
これは単にテキスト解析の問題です。各行の最初の行を-
次に変換します+
。
$ sed 's/-/+/' two.txt
+20 35.74
+18 35.74
+16 35.74
+14 35.74
+12 35.74
+0 35.74
各行の最初の番号の前に1つを追加します-
(ファイルの前にスペースがあるようです)。
$ sed -E 's/[0-9]/-&/' one.txt
-10 35.74
-8 35.74
-6 35.74
-4 35.74
-2 35.74
-0 35.74
ファイルに質問に表示される先行スペースがない場合は、次のように単純化できます。
sed -E 's/^/-/' one.txt
-i
すべての場合にファイルの内部編集を使用できます。
sed -i 's/-/+/' two.txt
sed -i -E 's/[0-9]/-&/' one.txt
答え3
負のゼロは整数 C データ型には適用されません。数値に小数部がない場合、awkはを使用するのと同じように文字列に変換しますprintf("%ld")
。
シンボルを保存するには、-0
次のものが必要です。
awk '{$1 = sprintf("%g", -$1); print}'
注意すべき点は%g
精度が6桁で、大きな数字については工学表記法に切り替えられます。%15g
たとえば、より良い精度のためにに置き換えることができます。
文字列と数字の間を前後に変換せずにテキストとして実行できます。
perl -pe 's{(-?)(?=\d)}{$1 ? "" : "-"}e'
これは、フィールド間の間隔を変更しないという利点もあります。ファイルをその場で編集する-i
オプションを渡すこともできますperl
(その後、標準入力ではなく引数として渡す必要があります)。
答え4
$ awk '!sub(/-/,"",$1){$1="-"$1} 1' one.txt
-10 35.74
-8 35.74
-6 35.74
-4 35.74
-2 35.74
-0 35.74
$ awk '!sub(/-/,"",$1){$1="-"$1} 1' two.txt
20 35.74
18 35.74
16 35.74
14 35.74
12 35.74
0 35.74