괄호 안의 숫자를 찾아 반올림하세요.

괄호 안의 숫자를 찾아 반올림하세요.

다음과 같은 줄을 포함하는 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자리로 반올림되는 둥근 버전으로 바꿔야 합니다. 따라서 위의 두 줄에 대한 출력은 다음과 같습니다.

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

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동일한 목표를 달성하지만 그가 권장하는 도구를 사용할 수 있다면 아마도 더 빨라질 것입니다.

하지만 우리의 논리에는 한 가지 눈에 띄는 예외가 있습니다. 이것은 분기 테스트를 사용하므로 GNU가 필요합니다.sed- 문자열을 반복하여 누락 가능성을 찾습니다. Gilles는 검색하기 전에 문자열의 사용되지 않는 부분을 인쇄하고 제거하므로 속도가 더 빨라질 수 있습니다. 둘 중 하나를 선택해야 한다면 나는 그를 선택할 것이다. 그럼에도 불구하고 나는 이 대답만으로도 충분하다고 믿는다.

관련 정보