括弧内の数字を見つけて丸めます。

括弧内の数字を見つけて丸めます。

次の行を含むtables.tex(プロローグを含むtex用にフォーマットされた多くのテーブル)というファイルがあるとします。

some words (xyz, abc) & 0.00071 (0.07846) & 0.00411 (-0.13542) \\
some more words (1) & 0.00341 (-0.59991) & 0.00001 (0.99453) \\

二重バックスラッシュで終わる行で、最初の「&」を除く括弧内のすべての数字を見つけて、3桁に丸められた丸いバージョンに置き換える必要があります。したがって、上記の2行の出力は次のようになります。

some words (xyz, abc) & 0.00071 (0.078) & 0.00411 (-0.135) \\
some more words (1) & 0.00341 (-0.600) & 0.00001 (0.995) \\

これを行う最も効率的な方法は何ですか?このサイトでは、さまざまな方法(数値の丸め、括弧内の数字の印刷、awk、perlなど)でこれを行う方法の一部を説明する答えを見つけましたが、すべてを1つにまとめる(実際に動作する)スタイルに苦しんでいます。

答え1

AwkまたはPerlはこれに適したツールです。 Perlは正規表現のマッチングに任意のコードを適用できるため、実装が簡単です。

perl -pe '
    if (s/^([^&]*&)//) {             # if there's a &, then strip the prefix…
        print $1;                    # and print it
        s[\((-?[0-9]*\.[0-9]+)\)]    # replace decimal numbers in parentheses…
         [sprintf("(%.3f)",$&)]eg    # …by their rounding
    }
'

答え2

. 4<<HERE /dev/fd/4
    echo "$(sed -rn '/\\\\/{:l;s/([^&]*&.*\()([-0-9.]*)(\).*)/\
        "\1$(printf "%.3f" "\2" )\3"/;tl;p;}'<<\SED
    some words (xyz, abc) & 0.00071 (0.07846) & 0.00411 (-0.13542) \\
    some more words (1) & 0.00341 (-0.59991) & 0.00001 (0.99453) \\ 
    SED
    )"
HERE

出力:

some words (xyz, abc) & 0.00071 (0.078) & 0.00411 (-0.135) \\
some more words (1) & 0.00341 (-0.600) & 0.00001 (0.995) \\

明らかに、これは@Gillesの答えと非常によく似ています。ただ気づきました。私たち両方printf丸めを完了します。私はそれがおそらくこの場合与えられたと思います。なぜならそれがすることだからです。もちろん、これはシェル構成のみを使用します。sed同じ目標を達成しますが、彼が推奨するツールを使用できる場合は、おそらくより速くなります。

しかし、私たちのロジックには1つの顕著な例外があります。これは分岐テストを使用するので、GNUが必要です。sed- 文字列を繰り返して、欠落している可能性を見つけます。 Gilles は、検索前に文字列の未使用部分を印刷して削除するため、速度が速くなる可能性があります。どちらかを選択する必要がある場合は、私は彼を選択します。それにもかかわらず、私はこの答えだけで十分だと信じています。

関連情報