CSV 파일의 일련 번호만 표시하는 Grep 정규식(정의된 길이에는 문자와 숫자가 포함됨)

CSV 파일의 일련 번호만 표시하는 Grep 정규식(정의된 길이에는 문자와 숫자가 포함됨)

나는 (Cisco) 일련 번호를 포함하는 (거대하고 혼란스러운) CSV 파일을 많이 가지고 있습니다.

내 목표는 이를 추출하는 것입니다(btw: 나중에 Cisco API를 호출하여 서비스/지원 범위 피드백을 받으세요).

이제 이 CSV 파일을 처리하는 올바른 방법을 찾고 있습니다.

다른 방법이 있는지, 그리고 [:alpha:]와 [:digit:]의 조합을 포함하는 명명된 클래스를 사용하는 초기 "이동" 방법이 작동하지 않는 이유가 무엇인지 궁금합니다.

일련 번호를 해독하기 위해 구성 방법은 다음과 같습니다.

Cisco S/N 형식은 LLLYYWWXXXX입니다.

LLL = 위치 코드(예: FOC = Foxconn China)

YY = 연도 코드(08 = 2004...09=2005...etc...)

WW = 주 코드(주 01~52)

XXXX = Base-34 영숫자 고유 식별자(0~9 및 I와 O를 제외한 전체 알파벳 포함)

원천:https://community.spiceworks.com/how_to/96973-cisco-device-serial-number-explanation

# Doesn't Work

grep -E -o -w "[[:alnum:]]{11}" Inventory.csv | head
Description
UNIVERSALK9
techsupport
FCW203.....
UNIVERSALK9
techsupport
FCW203.....
UNIVERSALK9
techsupport
FDO201.....
[..]

# Does work

grep -o -w -P '([A-Z]){3}[0-9]{4}[[:alnum:]]{4}' Inventory.csv
FCW1234A1EF
FCW1234A1NG
FDO1234A1KB
FDO1234A103
FOC1234A137
FCW1234A10A
FOC1234A1GH
FOC1234A1GU
[..]

답변1

정규 표현식과 마찬가지로 원래 grep이 너무 "느슨"했습니다. [[:alnum:]]{11}Cisco가 아닌 일련 번호 용어를 허용하는 11개의 "영숫자"를 의미하도록 요청하셨습니다 .

  • 기술적 지원
  • 설명하다
  • 유니버설 솔크9

두 번째 grep은 "더 제한적"입니다. 즉, 일치하는 항목이 더 제한적입니다. 아직은 아니야엄청난그러나 Cisco 일련 번호에는 두 가지 옵션이 있습니다.

  • [0-9]{4}0부터 9까지 4자리 숫자를 허용합니다. 이렇게 하면 0899또는와 같은 잘못된 "주" 데이터가 허용됩니다 0900.
  • [[:alnum:]]{4}I금지된 합계를 허용하는 4개의 영숫자 문자를 허용합니다 O.

두 번째 grep은 모든 Cisco 일련 번호를 캡처합니다.필요 이상이지만 잘못된 일련 번호를 허용하도록 속일 수도 있습니다.

나는 아마도 강력한 패턴 일치와 문자열 조작을 허용하기 때문에 지저분한 파일에 awk를 사용할 것입니다. 다음 awk 스크립트는 높은 수준에서 두 가지 작업을 수행합니다.

  1. 각 입력 줄을 반복하면서 Cisco 일련 번호일 수 있는 항목을 찾습니다.
  2. 이러한 입력 라인에서 각 잠재적 일치 항목을 찾습니다. 일치 항목이 있을 때마다 일련 번호가 추출되고 추가 테스트가 수행됩니다("주" 값이 유효한지 확인). 이러한 값이 무엇으로 예상되는지에 대해 더 자세히 알고 있는 경우 여기에서 "연도" 테스트를 수행할 수 있습니다. 더 작은 위치 집합을 표시하려는 경우 위치 코드에도 동일하게 적용됩니다.

내가 한 유일한 일은 정규식을 Base-34 부분과 더 밀접하게 정렬되도록 조정하는 것이었습니다.

스크립트는 다음과 같습니다.

awk '
        BEGIN {
                recisco="[A-Z]{3}[0-9]{4}[0-9ABCDEFGHJKLMNPQRSTUVWXYZ]{4}"
        }
        $0 ~ recisco {
                while(match($0, recisco) > 0) {
                        week=substr($0, RSTART+5, 2);
                        if (week > 1 && week < 54) {
                                print "Found: "substr($0,RSTART,RLENGTH)
                        }
                        $0=substr($0, RSTART+RLENGTH);
                }
        }'

관련 정보