질문 출력에서 ​​첫 번째 열의 양수를 어떻게 추출할 수 있나요?

질문 출력에서 ​​첫 번째 열의 양수를 어떻게 추출할 수 있나요?

저는 Ubuntu 14.04.1 LTS 64비트를 실행 중이고 다음과 같은 출력 생성이라는 프로그램이 Bash 4.3.11(1)-release있습니다 .harminv

$ h5totxt hsli0.126.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 
# harminv: 1902 inputs, dt = 0.1
frequency, decay constant, Q, amplitude, phase, error
# searching frequency range 0.31831 - 0.477465
# using 200 spectral basis functions, density 6.60692
-2.14026, 3.511909e-05, 30471.5, 0.922444, 1.26783, 1.383955e-06
2.14013, 2.052504e-05, 52134.7, 0.920264, -1.27977, 3.426846e-07
# harminv: 2/6 modes are ok: errs <= 1.000000e-01 and inf * 3.426846e-07
, amps >= 0, 9.000000e-01 * 0.922444, |Q| >= 10

-v(verbose) 옵션을 생략 하면 다음과 같이 더 간결한 출력을 얻습니다.

$ h5totxt hsli0.126.h5 | harminv -t 0.1 -w 2-3 -a 0.9 -f 200 
frequency, decay constant, Q, amplitude, phase, error
-2.14026, 3.511909e-05, 30471.5, 0.922444, 1.26783, 1.383955e-06
2.14013, 2.052504e-05, 52134.7, 0.920264, -1.27977, 3.426846e-07

두 경우 모두 출력의 첫 번째 열에서 양수를 추출할 수 있기를 원하지만 이를 수행하는 방법을 모릅니다. 또는 를 사용할 수 sed있습니다 awk. 누군가가 나에게 올바른 방향을 알려준다면 감사할 것입니다. 내 목표는 모든 양수를 기록하여 다른 변수에 대해 플롯하는 것입니다.

답변1

sed 사용

그러면 양수로 시작하는 줄만 인쇄됩니다.

sed -n 's/^\([[:digit:]][^ ,]*\).*/\1/p'

파이프라인 중 하나와 결합하면 다음과 같습니다.

h5totxt hsli0.126.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 | sed -n 's/^\([[:digit:]][^ ,]*\).*/\1/p'

어떻게 작동하나요?

  • -n

    이는 sed우리가 명시적으로 요청하지 않는 한 어떤 줄도 인쇄하지 말라고 지시합니다.

  • s/^\([[:digit:]][^ ,]*\).*/\1/p

    이는 sed양수로 시작하는 줄을 찾아 해당 숫자만 인쇄하라는 의미입니다.

    정규식에서는 ^줄의 시작 부분만 일치합니다. [[:digit:]]모든 숫자와 일치합니다. [^ ,]*숫자 뒤의 모든 항목과 일치합니다(공백이나 쉼표 제외). 나중에 해당 번호를 호출할 수 있도록 괄호로 그룹화되어 있습니다 \1. 그런 다음 전체 줄이 숫자로 바뀌고 옵션을 통해 인쇄하도록 p지시합니다 .sed

    숫자와 일치하는 하나입니다 [0-9]. 유니코드 글꼴의 출현으로 인해 이는 더 이상 신뢰할 수 없습니다. [[:digit:]]그러나 표현식은 유니코드로부터 안전합니다.

확장 정규식 사용의 대안

모든 Linux 시스템의 경우와 마찬가지로 GNU sed를 사용하는 경우 이 -r옵션을 사용하여 다음을 얻을 수 있습니다.확장 정규식. 확장 정규식을 사용하면 그룹화에 사용되는 대괄호를 이스케이프할 필요가 없습니다.

sed -rn 's/^([[:digit:]][^ ,]*).*/\1/p'

OSX 또는 기타 BSD 시스템에서는 -E대신 -r.

awk를 사용하세요

동일한 작업을 수행하지만 다음을 사용합니다 awk.

awk -F, '/^[[:digit:]]/{print $1}'

파이프라인과 결합:

h5totxt hsli0.126.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 | awk -F, '/^[[:digit:]]/{print $1}'

답변2

표시된 입력을 고려하면 다음이 작동합니다.

sed -n 's/[^[:digit:]]/\
&/;/.\n/P'

...또는...

sed 's/[^[:digit:]].*//;/./!d'

...어떤 sed경우에는 이렇게 쓸 수도 있습니다...

sed -n 's/[^0-9]/\n&/;/.\n/P'

...또는...

sed 's/[^0-9].*//;/./!d'

...아마도 - 입력 데이터 세트에 따라 - GNU 사용 sed, 예를 들어...

sed -n 's/\W/\n&/;/.\n/P'

...또는...

sed 's/\W.*//;/./!d'

정규 언어는 기본적으로 보완에 대한 설명이므로 거의 항상 정규식을 완전히 변경할 수 있습니다. 때로는 이로 인해 작업량이 줄어듭니다.

따라서 문자열 머리 부분에서 길이를 알 수 없는 특정 패턴을 검색하는 경우 패턴과 일치하지 않는 문자열의 첫 번째 부분을 찾는 것이 더 간단할 수 있습니다.

위의 첫 번째 예에서는 \n행에서 처음으로 나타나는 숫자가 아닌 문자 앞에 줄 바꿈 문자를 삽입합니다. 그런 다음 작동하는지 확인합니다.(이렇게 하면), 삽입된 내용과 줄의 시작 사이에 최소한 한 문자. 그렇지 않은 경우에는 인쇄하지 않고, 그렇다면 \n삽입된 행에만 인쇄합니다.

다음 예는 비슷합니다. 패턴과 일치하지 않는 문자로 시작하는 줄에서 가장 긴 문자열을 제거한 다음 출력에서 ​​모든 빈 줄을 제거합니다.

나머지는 일부 가 해석할 수 있는 것과 동일한 작업을 더 많이 수행하기 위한 약어일 뿐입니다 sed. 하지만 처음 두 개는 POSIX sed구문 사양을 매우 엄격하게 준수합니다.[[:digit:]]( UTF-8이 ASCII의 상위 집합이고 아라비아 숫자를 포함하지 않는 대부분의 언어가 이 코드를 작성하는 언어와 매우 다르다는 것을 이해하기 때문에 이것은 약간 과잉일 수 있습니다. 어쨌든 작동하려면 추가 수정이 필요합니다..

모든 예제(구현 및 주석 입력에 따라 다름)는 줄의 시작 부분부터 시작하여 첫 번째로 일치하는 연속 숫자 시퀀스만 인쇄해야 합니다.

그래도 생각해 보면 공백과 쉼표로 구분하는 것 같으니 다음과 같이 쓸 수도 있을 것 같습니다.

sed -n 'y/, -/\n\n\n/;/^[0-9]/P'

...실제 정규식 일치가 거의 없음 - y///함수 로서번역하다패턴별로 그룹화하는 대신 문자를 사용하세요. 정규식 일치자는 결과 테스트에만 사용됩니다.

관련 정보