저는 Linux를 배우고 있는데, 스스로 해결하지 못하는 것 같습니다. 여기있어:
한 행에 4 개의 숫자를 포함하지만 4를 초과하지 않는 파일에서 행을 grep하십시오.
어떻게 접근 해야할지 모르겠습니다. 문자열에서 특정 숫자는 검색 할 수 있지만 그 숫자는 검색 할 수 없습니다.
\b\d{4}\b
저는 Linux를 배우고 있는데, 스스로 해결하지 못하는 것 같습니다. 여기있어:
한 행에 4 개의 숫자를 포함하지만 4를 초과하지 않는 파일에서 행을 grep하십시오.
어떻게 접근 해야할지 모르겠습니다. 문자열에서 특정 숫자는 검색 할 수 있지만 그 숫자는 검색 할 수 없습니다.
\b\d{4}\b
답변:
이 질문을 해석하는 두 가지 방법이 있습니다. 두 경우 모두 해결하겠습니다. 라인을 표시 할 수 있습니다.
예를 들어 (1)은을 표시 1234a56789
하지만 (2)는 표시하지 않습니다.
더 이상 일련의 숫자가 아닌 일련의 4 자리 숫자를 포함하는 모든 행을 표시하려면 한 가지 방법이 있습니다.
grep -P '(?<!\d)\d{4}(?!\d)' file
이것은 Perl 정규 표현식을 사용하는데 , 우분투 grep
( GNU grep )는 via를 지원합니다 -P
. 와 같은 텍스트와 일치하지 않거나 그 일부 또는 12345
일치하지 않습니다 . 하지만 그것은 일치 의를 .1234
2345
1234
1234a56789
Perl 정규식에서 :
\d
는 모든 숫자를 의미합니다 ( [0-9]
또는 말하기 쉬운 방법입니다 [[:digit:]]
).x{4}
x
4 번 일치합니다 . ( {
}
구문은 Perl 정규 표현식에만 국한된 것이 아니라 확장 정규 표현식 grep -E
에도 적용됩니다.) \d{4}
와 동일합니다 \d\d\d\d
.(?<!\d)
너비가 0 인 음수 룩 어설 션입니다. "이 앞에 오지 않는 한"을 의미합니다 \d
.(?!\d)
너비가 0 인 네거티브 미리보기 어설 션입니다. "이 뒤에 오지 않으면"을 의미합니다 \d
.(?<!\d)
그리고 (?!\d)
네 자리 숫자의 순서 외부 텍스트와 일치하지 않는다; 대신, (함께 사용될 때) 긴 자릿수의 일부인 경우 네 자릿수의 시퀀스 자체가 일치하지 않도록합니다.
가장 오른쪽 또는 가장 왼쪽에있는 4 자리 하위 시퀀스가 여전히 일치하므로 Look-Behind 또는 Look-Ahead를 사용하는 것만으로는 충분하지 않습니다.
look-behind 및 look-ahead 어설 션 을 사용하면 패턴이 주변 텍스트가 아닌 4 자리 시퀀스 만 일치한다는 이점 이 있습니다. 이 --color
옵션 은 색상 강조 표시를 사용할 때 유용합니다 ( 옵션 포함).
ek@Io:~$ grep -P '(?<!\d)\d{4}(?!\d)' <<< 12345abc789d0123e4
12345abc789d0123e4
기본적으로 우분투, 각 사용자가 alias grep='grep --color=auto'
자신의 ~.bashrc
파일 . 따라서 grep
( 별칭 이 확장되는 경우)로 시작하는 간단한 명령을 실행 하고 표준 출력 이 터미널 (이것이 확인하는 것) 인 경우 색상 강조 표시가 자동으로 나타납니다 . 일치 항목은 일반적으로 빨간색 음영 ( vermilion에 가까운 ) 으로 강조 표시 되지만 기울임 꼴 굵은 체로 표시되었습니다. 스크린 샷은 다음과 같습니다.--color=auto
또한 다음 grep
과 같이 전체 줄이 아닌 일치하는 텍스트 만 인쇄 할 수 있습니다 -o
.
ek@Io:~$ grep -oP '(?<!\d)\d{4}(?!\d)' <<< 12345abc789d0123e4
0123
그러나 다음과 같은 경우 :
grep
지원하지 않는 -P
펄 정규 표현식을 사용하지 않으려는 달리 또는, 및... 그러면 확장 정규 표현식을 사용 하여이를 달성 할 수 있습니다 .
grep -E '(^|[^0-9])[0-9]{4}($|[^0-9])' file
네 자리 숫자와 숫자가 아닌 문자 (또는 줄의 시작 또는 끝)와 일치합니다. 구체적으로 :
[0-9]
모든 숫자 (예 [[:digit:]]
: 또는 \d
Perl 정규식)와 일치 {4}
하며 "네 번"을 의미합니다. 따라서 [0-9]{4}
네 자리 시퀀스와 일치합니다.[^0-9]
하지 않는 범위에서 문자와 일치 0
를 통해 9
. 그것은과 동일 [^[:digit:]]
(또는 \D
펄 정규 표현식으로).^
[
]
괄호 안에 표시되지 않으면 줄의 시작과 일치합니다. 마찬가지로 $
줄의 끝과 일치합니다.|
평균 또는 괄호는 대수에서와 같이 그룹화하기위한 것입니다. 따라서 (^|[^0-9])
줄의 시작 또는 숫자가 아닌 문자 ($|[^0-9])
와 일치하는 반면 줄의 끝 또는 숫자가 아닌 문자 와 일치합니다.따라서 일치 [0-9]{4}
는 동시에 네 자리 시퀀스 ( )를 포함하는 행에서만 발생합니다 .
(^|[^0-9])
)가 있고($|[^0-9])
)가 옵니다 .반면에, 당신은 네 자리 시퀀스를 포함하는 모든 행을 표시하는 것이 아니라 포함되지 않은하려면 어떤 개념적으로 다음, 이상 네 자리 (네 개의 숫자의 또 다른 시퀀스와 분리 된 경우에도 하나)의 순서를 당신의 목표는 한 패턴과 일치하지만 다른 패턴과 일치하지 않는 선을 찾는 것입니다.
따라서 단일 패턴으로 수행하는 방법을 알고 있더라도 matt의 두 번째 제안 과 같은 것을 사용 grep
하여 두 패턴을 따로 제안 하는 것이 좋습니다 .
이를 수행 할 때 Perl 정규식의 고급 기능을 강하게 활용하지 않기 때문에 사용하지 않는 것이 좋습니다. 그러나 위의 스타일을 유지하기 위해 다음 대신에 (및 중괄호)를 사용 하는 matt의 솔루션 이 단축 \d
되었습니다 [0-9]
.
grep -P '\d{4}' file | grep -Pv '\d{5}'
그것은 사용하기 때문에 [0-9]
, 매트의 방법은 더 휴대용 - 그것은 시스템에서 작동 grep
펄 정규 표현식을 지원하지 않습니다. 당신이 사용하는 경우 [0-9]
(또는 [[:digit:]]
) 대신 \d
하지만, 계속 사용 {
}
하면 매트의 방식의 휴대 성을 좀 더 간결하게 얻을 :
grep -E '[0-9]{4}' file | grep -Ev '[0-9]{5}'
당신이 정말로 grep
명령을 선호한다면
grep
구분 된 두 개가 아님 )... 다음을 사용할 수 있습니다.
grep -Px '(\d{0,4}\D)*\d{4}(\D\d{0,4})*' file
-x
플래그 차종은 grep
오직 선을 표시 곳 전체 라인 일치 (보다는 어떤 라인을 포함 일치).
나는 Perl 정규식을 사용했다. 왜냐하면 나는 이 경우 의 간결함이 간결 \d
하고 \D
명확성을 높이기 때문이다. 당신이 시스템에 휴대용 뭔가가 필요하지만 grep
지원하지 않습니다 -P
, 당신은 그들을 대체 할 수 [0-9]
및 [^0-9]
(또는과 [[:digit:]]
및 [^[:digit]]
) :
grep -Ex '([0-9]{0,4}[^0-9])*[0-9]{4}([^0-9][0-9]{0,4})*' file
이 정규 표현식의 작동 방식은 다음과 같습니다.
가운데 \d{4}
또는 [0-9]{4}
네 자리의 한 시퀀스와 일치합니다. 우리는 이것들 중 하나 이상을 가질 수 있지만, 적어도 하나는 있어야합니다.
왼쪽에서 (\d{0,4}\D)*
또는 4 자리 이하의 ([0-9]{0,4}[^0-9])*
0 개 이상의 *
인스턴스 ( ) 와 일치하고 숫자가 아닌 숫자 와 일치합니다 . 0 자리 숫자 (즉, 아무것도 아님)는 "4 자리 이하의 숫자"일 가능성이 있습니다. 이 경기 의 (a) 빈 문자열 또는 (b)에 임의의 문자열 끝 이 아닌 자리에서 이상 네 자리 숫자의 시퀀스를 포함하지 않는.
중앙 \d{4}
(또는 [0-9]{4}
) 의 바로 왼쪽에있는 텍스트 는 비어 있거나 숫자가 아닌 숫자로 끝나야하므로 중앙 \d{4}
에서 왼쪽에 다른 다섯 번째 숫자가있는 네 자리 숫자와 일치 하지 않습니다.
오른쪽에서 (\D\d{0,4})*
또는 숫자가 아닌 ([^0-9][0-9]{0,4})*
0 개 이상의 *
인스턴스와 그 뒤에 4 자리를 넘지 않습니다 (이전과 같이 4, 3, 2, 1 또는 전혀 없음). 이 경기 의 (a) 빈 문자열 또는 (b)에 임의의 문자열 시작 이 아닌 자리에서 이상 네 자리 숫자의 시퀀스를 포함하지 않는.
중앙 \d{4}
(또는 [0-9]{4}
) 의 바로 오른쪽에있는 텍스트 는 비어 있거나 숫자가 아닌 숫자로 시작해야하므로 중앙 \d{4}
에서 오른쪽에 다른 다섯 번째 숫자가있는 네 자리 숫자가 일치 하지 않습니다.
이를 통해 어딘가에 4 자리 시퀀스가 존재하고, 5 개 이상의 숫자 시퀀스가 어디에도 존재하지 않게됩니다.
이런 식으로하는 것은 나쁘거나 잘못이 아닙니다. 그러나이 대안을 고려해야 할 가장 중요한 이유 는 위에 제안 된 것과 매트의 대답 에서 대신 (또는 유사한) 사용의 이점을 분명히하기 때문 입니다.grep -P '\d{4}' file | grep -Pv '\d{5}'
그렇게하면 목표는 하나만 포함하고 다른 것은 포함하지 않는 줄을 선택하는 것이 분명합니다. 또한 구문이 더 간단합니다 (많은 독자 / 관리자가 더 빨리 이해할 수 있음).
이렇게하면 4 개의 숫자가 연속으로 표시되지만 더 이상은 표시되지 않습니다
grep '[0-9][0-9][0-9][0-9][^0-9]' file
^는
문제를 해결하는 방법을 모르겠지만 문제가 있습니다 ... 번호가 줄의 끝이면 표시되지 않습니다.
그러나이 추한 버전은 그 경우에 효과가 있습니다.
grep '[0-9][0-9][0-9][0-9]' file | grep -v [0-9][0-9][0-9][0-9][0-9]
a12345b
왜냐하면 그것이 일치하기 때문이다 2345b
.
경우 grep
펄 정규식을 (지원하지 않습니다 -P
), 다음 쉘 명령을 사용합니다 :
grep -w "$(printf '[0-9]%.0s' {1..4})" file
어디에서 printf '[0-9]%.0s' {1..4}
4 배를 생산할 것인가 [0-9]
. 이 방법은 긴 자릿수가 있고 패턴을 반복하지 않으려는 경우에 유용합니다 ( 4
찾을 자릿수로 바꾸 십시오).
를 사용 -w
하면 전체 단어를 찾습니다. 그러나와 같은 영숫자 문자열에 관심이 있다면 패턴의 끝에 1234a
추가하십시오 [^0-9]
.
grep "$(printf '[0-9]%.0s' {1..4})[^0-9]" file
사용 $()
은 기본적으로 명령 대체 입니다. 패턴을 반복하는 방법을 보려면 이 게시물 을 확인하십시오 printf
.
1234a12345
표시 해야합니까 ?