sed를 사용하여 알파벳 문자 2개가 포함된 줄만 찾아서 유지하세요.

sed를 사용하여 알파벳 문자 2개가 포함된 줄만 찾아서 유지하세요.

다음과 같은 줄이 많이 포함된 파일이 있습니다.

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자동으로 인쇄하도록 지시되었으므로 이제 -n3개 이상의 알파벳 문자가 포함된 입력 줄이 출력에서 ​​효과적으로 제거되고 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

관련 정보