1

コマンドの使用に関する 2 つの質問uniq、助けてください。

最初の質問

2 つのファイルがあるとします。

$ cat 1.dat
0.1 1.23
0.2 1.45
0.3 1.67

$ cat 2.dat
0.3 1.67
0.4 1.78
0.5 1.89

を使用するcat 1.dat 2.dat | sort -n | uniq > 3.datと、2 つのファイルを 1 つにマージできます。結果は次のとおりです。

0.1 1.23
0.2 1.45
0.3 1.67
0.4 1.78
0.5 1.89

1.datしかし、ファイルに科学表記法がある場合、

$ cat 1.dat
1e-1 1.23
0.2 1.45
0.3 1.67

結果は次のようになります。

0.2 1.45
0.3 1.67
0.4 1.78
0.5 1.89
1e-1 1.23

これは私が望むものではありません。文字列ではなく数値であることをどのようにuniq理解させることができますか。1e-1

2 番目の質問

上と同じですが、今度は 2 番目のファイル2.datの最初の行を少しだけ変更します (から0.3 1.670.3 1.57)

$ cat 2.dat
0.3 1.57
0.4 1.78
0.5 1.89

結果は次のようになります。

0.1 1.23
0.2 1.45
0.3 1.67
0.3 1.57
0.4 1.78
0.5 1.89

私の質問はこれuniqです。最初のファイルの値に基づいて使用し、最初の列からのみ繰り返しを見つけて、結果が次のようになるようにする方法は次のとおりです。

0.1 1.23
0.2 1.45
0.3 1.67
0.4 1.78
0.5 1.89

ありがとう

より複雑なテスト ケース

$ cat 1.dat
1e-6 -1.23
0.2 -1.45
110.7 1.55
0.3 1.67e-3
4

3 に答える 3

2

1つのawk(gnu awk)1つのライナーが2つの問題を解決します

  awk '{a[$1*1];b[$1*1]=$0}END{asorti(a);for(i=1;i<=length(a);i++)print b[a[i]];}' file2 file1

データを使用したテスト:注:必要に応じて、file1をソートせず1.57にfile2にしました。

kent$  head *
==> file1 <==
0.3 1.67
0.2 1.45
1e-1 1.23

==> file2 <==
0.3 1.57
0.4 1.78
0.5 1.89

kent$  awk '{a[$1*1];b[$1*1]=$0}END{asorti(a);for(i=1;i<=length(a);i++)print b[a[i]];}' file2 file1
1e-1 1.23
0.2 1.45
0.3 1.67
0.4 1.78
0.5 1.89

編集

0.1の代わりに表示1e-1

kent$  awk '{a[$1*1];b[$1*1]=$2}END{asorti(a);for(i=1;i<=length(a);i++)print a[i],b[a[i]];}' file2 file1
0.1 1.23
0.2 1.45
0.3 1.67
0.4 1.78
0.5 1.89

編集2

精度については、awk default(OFMT)%.6gを変更できます。しかし、線ごとに異なる精度を表示したい場合は、少しトリックが必要です。

(file1に1e-9を追加しました)

kent$  awk '{id=sprintf("%.9f",$1*1);sub(/0*$/,"",id);a[id];b[id]=$2}END{asorti(a);for(i=1;i<=length(a);i++)print a[i],b[a[i]];}'  file2 file1 
0.000000001 1.23
0.2 1.45
0.3 1.67
0.4 1.78
0.5 1.89

すべての行に同じ数値精度を表示する場合:

kent$  awk '{id=sprintf("%.9f",$1*1);a[id];b[id]=$2}END{asorti(a);for(i=1;i<=length(a);i++)print a[i],b[a[i]];}'  file2 file1 
0.000000001 1.23
0.200000000 1.45
0.300000000 1.67
0.400000000 1.78
0.500000000 1.89
于 2013-02-14T22:07:50.953 に答える
2

最初の部分のみ:

cat 1.dat 2.dat | sort -g -u

1e-1 1.23
0.2 1.45
0.3 1.67
0.4 1.78
0.5 1.89

man sort

  -g, --general-numeric-sort
          compare according to general numerical value

 -u, --unique
          with -c, check for strict ordering; without -c, output only the first of an equal run
于 2013-02-14T22:01:28.527 に答える
1

科学表記法を10進数に変更するには、Pythonに頼りました

#!/usr/bin/env python

import sys
import glob

infiles = []

for a in sys.argv:
    infiles.extend(glob.glob(a))

for f in infiles[1:]:
    with open(f) as fd:
        for line in fd:
            data = map(float, line.strip().split())
            print data[0], data[1]

出力:

$ ./sn.py 1.dat 2.dat
0.1 1.23
0.2 1.45
0.3 1.67
0.3 1.67
0.4 1.78
0.5 1.89
于 2013-02-14T22:15:40.247 に答える