저는 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///
함수 로서번역하다패턴별로 그룹화하는 대신 문자를 사용하세요. 정규식 일치자는 결과 테스트에만 사용됩니다.