다음과 같은 줄이 있다고 가정 해보십시오.
*[234]*
*[23]*
*[1453]*
여기서 *
모든 문자열을 나타냅니다 (형식의 문자열 제외 [number]
). 명령 행 유틸리티로 이러한 행을 구문 분석하고 대괄호 사이의 숫자를 추출하려면 어떻게해야합니까?
더 일반적으로, 이러한 도구의 어떤 cut
, sed
, grep
또는 awk
그러한 작업에 적합한 것입니까?
다음과 같은 줄이 있다고 가정 해보십시오.
*[234]*
*[23]*
*[1453]*
여기서 *
모든 문자열을 나타냅니다 (형식의 문자열 제외 [number]
). 명령 행 유틸리티로 이러한 행을 구문 분석하고 대괄호 사이의 숫자를 추출하려면 어떻게해야합니까?
더 일반적으로, 이러한 도구의 어떤 cut
, sed
, grep
또는 awk
그러한 작업에 적합한 것입니까?
답변:
GNU grep이 있다면 사용할 수 있습니다. -o
옵션을 하여 정규식을 검색하고 일치하는 부분 만 출력 . 다른 grep 구현은 전체 행만 표시 할 수 있습니다. 한 행에 여러 개의 일치 항목이있는 경우 별도의 행에 인쇄됩니다.
grep -o '\[[0-9]*\]'
대괄호가 아닌 숫자 만 원하면 조금 더 어려워집니다. 너비가 0 인 어설 션을 사용해야합니다. 빈 문자열과 일치하는 정규 표현식이지만 대괄호로 시작하거나 뒤에 오는 경우에만 가능합니다. 너비가 0 인 어설 션은 Perl 구문에서만 사용할 수 있습니다.
grep -P -o '(?<=\[)[0-9]*(?=\])'
sed를 사용하면로 인쇄를 끄고 -n
전체 줄을 일치시키고 일치하는 부분 만 유지해야합니다. 한 줄에 여러 개의 가능한 일치 항목이 있으면 마지막 일치 항목 만 인쇄됩니다. sed 사용에 대한 자세한 내용 은 주변 문자 를 인쇄하지 않고 'sed'와 일치하는 정규식 추출을 참조 하십시오.
sed -n 's/^.*\(\[[0-9]*\]\).*/\1/p'
또는 대괄호가 아닌 숫자 만 원하는 경우 :
sed -n 's/^.*\[\([0-9]*\)\].*/\1/p'
이 없으면 grep -o
단순하고 이해하기 쉬운 것을 원한다면 Perl을 선택하는 것이 좋습니다. 모든 행 ( -n
)에서 행에 대한 일치 항목이 있으면 \[[0-9]*\]
해당 일치 항목 ( $&
)과 줄 바꿈 ( -l
) 을 인쇄하십시오 .
perl -l -ne '/\[[0-9]*\]/ and print $&'
숫자 만 원하면 정규식에 괄호를 묶어 그룹을 구분하고 해당 그룹 만 인쇄하십시오.
perl -l -ne '/\[([0-9]*)\]/ and print $1'
PS 대괄호 사이에 하나 이상의 숫자 만 필요 [0-9]*
하면 [0-9][0-9]*
으로 또는 [0-9]+
펄로 변경하십시오.
perl
정규식 주장은 정말 유용하게 보입니다! grep 에서조차도 앞뒤 어설 션을 모두 사용하는 것을 본 후에 그들에 대해 읽었습니다 (정규식 엔진을 선택할 수 있다는 사실로 전환했습니다). 나는 여기서부터 perl의 정규식에 조금 더 시간을 할애 할 것입니다. 감사합니다 ... PS .. 방금 읽었습니다 man grep
. "이것은 매우 실험적이며 grep -P는 구현되지 않은 기능을 경고 할 수 있습니다." ... 그것이 불안정하지 않길 바래요 (?) ...
으로 할 수 없습니다 cut
.
tr -c -d '0123456789\012'
sed 's/[^0-9]*//g'
awk -F'[^0-9]+' '{ print $1$2$3 }'
grep -o -E '[0-9]+'
tr
문제에 가장 자연스럽게 적합하며 아마도 가장 빨리 실행될 수 있지만 속도면에서 이러한 옵션을 분리하려면 거대한 입력이 필요하다고 생각합니다.
^.*
욕심이고 모든하지만 마지막 숫자를 소모하며, +
요구로 \+
그렇지 않으면 POSIX를 사용 \([0-9][0-9]*\)
.... 그리고 어떤 경우에 's/[^0-9]*//g'
, 단지뿐만 아니라 작동 ... Thanks for the
그럴 -c` 예,하지만 후행되지 않도록 \012
surperfluous?
\012
: 그렇지 않으면 줄 tr
바꿈 이 필요할 것입니다.
\0
, 1
, 2
(또는 \, 0, 1, 2). 8 진수로 보일 정도로 조율되지 않았습니다. 감사합니다.
당신은 숫자가 아닌 문자 사이의 연속적인 숫자의 집합을 추출 의미, 내가 생각 sed
하고 awk
(비록 최고grep
또한 당신에게 일치하는 문자를 제공 할 수 있습니다)
sed
: 물론 숫자와 일치 할 수는 있지만 반대의 작업은 숫자가 아닌 숫자를 제거하는 것이 흥미로울 것입니다 (한 줄에 하나의 숫자 만있는 한 작동합니다).
$ echo nn3334nn | sed -e 's/[^[[:digit:]]]*//g'
3344
grep
: 연속 숫자와 일치시킬 수 있습니다
$ echo nn3334nn | grep -o '[[:digit:]]*'
3344
나는 그것에 대한 awk
경험이 없기 때문에 예를 들지 않는다 . sed
스위스 칼 이지만 이 grep
작업을 수행하는보다 간단하고 읽기 쉬운 방법을 제공합니다.이 방법은 각 입력 줄에서 둘 이상의 숫자에 대해서도 작동합니다 (입력 -o
의 일치하는 부분 만 인쇄합니다) 자체 라인에서) :
$ echo dna42dna54dna | grep -o '[[:digit:]]*'
42
54
sed
의 eqivalent "두 개 이상의 전화 번호 줄에" 예 grep -o '[[:digit:]]*'
. . . sed -nr '/[0-9]/{ s/^[^[0-9]*|[^0-9]*$//g; s/[^0-9]+/\n/g; p}'
... (+1)
이것으로 할 수 없다고 말했기 때문에 cut
, 나는 cut
"최고의"로서의 사용을 보증하지는 않지만 다른 것보다 적어도 나쁘지 않은 솔루션을 만드는 것이 쉽게 가능하다는 것을 보여줄 것입니다. (또는 심지어 특히 좋은) 솔루션. 어떤 용액 특별히 보지 않고 있다고해야 *[
하고 ]*
가정을 단순화하게 자리 주위 및 실시 예에 아스카 의해 주어진 다음 중 하나 (예를 들어 숫자 외부보다 더 복잡하기 때문에, 고장이 경향 *[
과 ]*
도시되지 않아야). 이 솔루션은 최소한 괄호를 확인하고 별표도 확인하도록 확장 할 수 있습니다 (독자의 연습으로 남음).
cut -f 2 -d '[' myfile.txt | cut -f 1 -d ']'
이것은 -d
구분자를 지정하는 옵션을 사용합니다. 분명히 cut
파일에서 읽는 대신 표현식 으로 파이프 할 수도 있습니다. 하지만 cut
그것은 (아무 정규식 엔진) 간단하기 때문에, 꽤 빨리 아마, 당신은 그것을 호출이 두 번 이상 (또는 확인하기 위해 몇 시간에서 *
) 일부 프로세스 오버 헤드를 만듭니다. 이 솔루션의 한 가지 장점은 특히 정규 표현식 구조에 정통하지 않은 일반 사용자의 경우 읽기 쉽다는 것입니다.
[number]
"는 다음을 제외하고 의미 한다고 생각합니다.[0-9]