다음과 같은 줄이 많이 포함된 파일이 있습니다.
33B87401
33B87402
33B87403
33B8EE44
33B87405
33B87406
33B87407
33B87408
33B87409
33B8740A
33B8740B
33B8740C
33B87D0D
33B8740E
33B8740F
33B87410
33B87411
33B87C1E
33B87CC3
33B87C1C
알파벳 2개만 포함된 줄만 유지하는 방법을 찾고 있습니다.
이 예제의 출력은 다음과 같습니다.
33B8740A
33B8740B
33B8740C
33B8740E
33B8740F
여기 또 다른 목록이 있습니다
8765C3E3
8765C3E4
8765C3E5
8765C3E6
8765C3E7
8765C3E8
8765C3E9
8765C3EA
8765C3EB
8765C3EC
8765C3ED
8765C3EE
8765C3EF
8765C3F0
sed 및 awk의 많은 예제를 읽어보면 이를 재현하는 것이 불가능해 보입니다.
감사해요
답변1
sed -ne's/[[:alpha:]]//3;t' -e's//&/2p' <in >out
... 한 줄에 있는 클래스의 세 번째 문자를 s///
대체합니다 . [[:alpha:]]
그런 다음 t
교체가 성공했는지 확인하고 성공하면 스크립트에서 분기됩니다.
sed
자동으로 인쇄하도록 지시되었으므로 이제 -n
3개 이상의 알파벳 문자가 포함된 입력 줄이 출력에서 효과적으로 제거되고 s///
두 번째 바꾸기 문에 의해 남겨진 유일한 입력 줄은 2개 이하의 알파벳 문자가 포함된 행입니다.
두 번째 대체는 //
왼쪽의 빈 정규식을 사용합니다 sed
.(더 효율적)가장 최근에 컴파일된 것을 참조/
regexp
/
- 그래서 s/[[:alpha:]]/...
다시 읽을 수 있습니다. 이는 s///
한 줄에서 두 번째로 나타나는 알파벳 문자를 &
그 자체로 바꾸려고 시도하므로 효과적인 no-op가 발생하고 줄이 실제로 수정되지 않습니다. 그러나 이 작업이 성공적으로 수행되면 해당 행도 p
출력에 인쇄됩니다.
요약하자면, 첫 번째 s///
대체는 3개 이상의 알파벳 문자와 일치하는 모든 입력 행을 출력에서 효과적으로 제거하고, 두 번째 대체는 p
나머지를 두 개의 알파벳 문자와 일치하는 입력 행만 출력하도록 남겨둡니다.
...와/ grep
...
grep -xE '([0-9]*[[:alpha:]]){2}' <in >out
성명서는 요청한 대로 정확히 따르지 않습니다. 입력에서 영숫자 문자로만 구성된 줄만 선택하고 해당 하위 집합 내에서 두 글자 이하로 일치하는 줄만 선택합니다. 여기서 두 번째 글자는 마지막 문자여야 합니다. 이 문은 예제 입력에서 예제에 필요한 출력을 생성합니다.
그러나 요청받은 대로 수행하십시오.
grep -xE '([^[:alpha:]]*[[:alpha:]]){2}[^[:alpha:]]*'
이 명령문은 입력 줄의 어느 곳에서나 찾을 수 있고 ^
알파벳이 아닌 문자로 구분할 수 있는 두 개의 알파벳 문자와 일치하는 입력 줄을 선택합니다.
grep
스위치 -x
는 두 경우 모두에 사용됩니다. 그러나 ^
줄 시작 앵커와 $
줄 끝 앵커가 정규식에 각각 추가(앞에 | 추가)되면 두 명령문 중 하나를 생략할 수 있습니다. 이 -x
스위치는전반적으로일치 - 따라서 정규 표현식은 일치하는 모든 입력 줄을 처음부터 끝까지 완벽하게 설명해야 합니다.
답변2
나는 다음을 사용할 것이다 perl
:
perl -ne 'print if length s/\d//gr == 2'
다음을 사용합니다:
-n
암시적 래핑while ( <> ) {
루프s///r
원본 텍스트를 수정하지 않고 대체된 텍스트를 반환합니다.- 따라서 모든 숫자를 제거한 다음 문자열 길이를 살펴보겠습니다.
- 2이면 행을 인쇄하십시오.
참고: 이렇게 하면 행에서 숫자가 제거되고 숫자가 아닌 숫자는 남게 됩니다. 대신 이것을 사용할 수 있습니다 [^A-Z]
.
또는 - 더 명확한 경우:
perl -ne 'print if (()=m/([A-Z])/g) == 2'
이는 perl
이 플래그를 지원하지 않는 이전 버전에서 작동합니다 r
. 정규식 일치를 사용하여 텍스트를 선택하고 배열 요소(일치)의 수를 계산합니다. 2이면 행을 인쇄하십시오.
답변3
방금 여러분이 원하는 것을 정확히 수행하는 간단한 Python 스크립트를 작성했고, 여러분의 입력에 대해 테스트했는데 잘 작동합니다.
#!/usr/bin/python
def count_letters(input):
count=0
for char in input:
if char.isalpha():
count += 1
return count
fh=open('test_input','r')
for line in fh.readlines():
if count_letters(line) == 2 :
print line
답변4
그리고awk
awk '{x=$0; gsub(/[^[:alpha:]]/, "", x)};length(x) == 2' file
이렇게 하면 각 줄을 변수로 설정한 다음 x
그 안의 알파벳이 아닌 모든 문자를 빈 문자열로 바꿉니다. x
수정된 길이가 다음 x
과 같은 경우 2
관련 행이 적합합니다 .
아니면grep
grep '^[^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*$' file