Linux에서 정규식을 사용하여 특정 필드 인쇄

Linux에서 정규식을 사용하여 특정 필드 인쇄

이라는 파일에서 네 번째 필드 값이 1001 또는 1003인 행을 인쇄하려고 합니다 mypasswd. 정규식에는 grep이나 egrep만 사용할 수 있습니다. 파일은 다음과 같습니다.

daemon:x:2:2:Daemon 1001:/sbin:/bin/bash
ftp:x:40:49:FTP export account:/srv/ftp:/bin/bash
daemonuser:x:50:59:nouser/bin/false:/home/nouser:/bin/bash
gdm:x:106:111:Gnome Display Mgr daemon:/var/lib/gdm:/bin/false
haldaemon:x:101:102:User for haldaemon:/var/run/hald:/bin/false
lp:x:4:7:Printing daemon:/var/spool/lpd:/bin/bash
mail:x:8:12:Mailer daemon:/var/spool/clientmqueue:/bin/false
root:x:0:0:root:/root:/bin/bash
sshd:x:71:65:SSH daemon:/var/lib/sshd:/bin/false
olivert:x:1001:1005:Tom Oliver:/home/olivert:/bin/csh
smiths:x:1049:1000:Sue Williams:/export/home/smiths:/bin/csh
northj:x:1003:1003:Jim jones-North:/home/northj:/bin/csh
denniss:x:1005:1003:Sue Dennis:/home/denniss:/bin/bash
smitha:x:1050:1001:Amy Smith:/export/home/smitha:/bin/bash
jonesc:x:1053:1001:Cathy Jones:/export/home/jonesc:/bin/ksh
smithd:x:1055:1001:Dan Smith Jr:/export/home/smithd:/bin/csh

그래서 출력은 다음과 같아야합니다

northj:x:1003:1003:Jim jones-North:/home/northj:/bin/csh
denniss:x:1005:1003:Sue Dennis:/home/denniss:/bin/bash
smitha:x:1050:1001:Amy Smith:/export/home/smitha:/bin/bash
jonesc:x:1053:1001:Cathy Jones:/export/home/jonesc:/bin/ksh
smithd:x:1055:1001:Dan Smith Jr:/export/home/smithd:/bin/csh

이것을 쉽게 실행할 수 있지만 egrep '1001|1003' mypasswd"daemon"(다섯 번째 필드에 "1001"이 포함됨)과 "olivert"(세 번째 필드가 "1001"임)도 제공됩니다. egrep/grep regex를 사용하여 이 두 숫자의 네 번째 필드 값(콜론 3개 뒤의 값)만 일치시키면 됩니다. 모든 답변은 장기적으로 이 문제를 해결하는 데 도움이 되므로 크게 감사하겠습니다.

답변1

제 생각에는 다음과 같은 도구를 사용하는 것이 더 간단할 것 같습니다 awk.

  • 당신을 위해 필드 분할
  • 원하는 값을 얻고 싶은 필드를 정확하게 테스트하세요.

예를 들어:

awk -F: '$4 == 1001 || $4 == 1003' mypasswd

...알아봐:

  • 들어오는 행을 콜론을 기준으로 필드로 분할합니다.-F:
  • "or" 표현식을 사용하여 필드 4의 값이 1001인지 1003인지 테스트합니다.
  • 위 조건이 true이면 해당 라인을 인쇄합니다(기본 동작).

awk를 배우는 데 약간의 시간이 걸립니다. 이해해야 할 주요 사항 중 하나는 "모드" 및 "작업" 문 쌍을 사용한다는 것입니다. "모드" 부분은 어떤 "작업" 문이 실행되는지 결정합니다.

위의 awk를 더 명시적으로 다시 작성할 수 있습니다. 이렇게 하면 원하는 것을 명시적으로 인쇄할 수 있습니다(예: 5번째 필드).

awk -F: '$4 == 1001 || $4 == 1003 { print $5 }'

...또는 빈 "모드" 섹션이 있습니다. 즉, "작업"을 수행한다는 뜻입니다.모든줄을 선택한 다음 작업 모드 내에서 값을 테스트합니다.

awk -F: '{ if ($4 == 1001 || $4 == 1003)  print $5 }'

강제로 grep조치를 취하려면 다음을 수행하십시오.

grep -E '^([^:]*:){3}(1001|1003):' mypasswd | cut -d: -f5

줄의 시작 부분에서 시작하여 "콜론이 아닌 모든 항목, 횟수 제한 없음" 그룹을 세 번 찾은 다음 1001 또는 1003을 찾은 다음 전체 일치하는 줄을 인쇄하도록 지시합니다. 그런 다음 이를 전달하여 cut5번째 필드만 인쇄합니다.

답변2

난 이걸 할 수도 있어sed

sed -n '/^.*:.*:.*:\(1001\|1003\):/p' mypasswd

줄을 억제 -n하고 p끝에 일치하는 줄을 인쇄합니다.

당신은 또한 이것을 할 수 있습니다grep

grep '^.*:.*:.*:1002\|1003:.*:.*:' mypasswd

답변3

@JeffSchaller가 말했듯 이 OP는 우리가 두 가지를 결합할 수 있기를 awk바랐기 때문에 이것이 작업을 수행하는 도구입니다.regex

awk -F: '$4 ~ /^100[13]$/' mypasswd

grep이 버전에서는 약간의 골프 퍼팅이 가능합니다.

grep -E "^(.*:){3}100[13]:" mypasswd

답변4

"egrep/grep regex를 사용하여 이 두 숫자의 네 번째 필드 값(콜론 세 개 뒤의 값)만 일치시키면 됩니다."

네 번째 필드만 필요한 경우 다음 cut과 같이 사용하세요 grep.

$ cat mypasswd | cut -d: -f4 | grep -E '^(1001|1003)$'
1001
1003

패턴 grep은 줄의 시작과 끝 부분에 고정되어야 합니다. 그렇지 않으면 와 같은 숫자와 일치할 수 있습니다 10010. 또 다른 방법은 입니다 grep -x -E '1001|1003'.

관련 정보