在 Linux 中使用正则表达式打印出特定字段

Jak*_*e M 8 grep text-processing regular-expression

我正在尝试从名为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
Run Code Online (Sandbox Code Playgroud)

所以输出应该是

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
Run Code Online (Sandbox Code Playgroud)

我可以轻松地运行egrep '1001|1003' mypasswd,但这也给了我“守护进程”(第五个字段包含“1001”)和“olivert”(第三个字段是“1001”)。我只需要使用 egrep/grep 正则表达式匹配这两个数字的第 4 个字段值(三个冒号之后的值)。非常感谢任何答案,因为从长远来看,它们会帮助我解决这个问题。

Jef*_*ler 16

在我看来,使用这样的工具会更直接awk

  • 为您拆分字段
  • 准确测试您想要的字段以获得您想要的值

例如:

awk -F: '$4 == 1001 || $4 == 1003' mypasswd
Run Code Online (Sandbox Code Playgroud)

... 告诉 awk:

  • 根据冒号将传入行拆分为字段,其中 -F:
  • 使用“或”表达式来测试字段 4 的值是 1001 还是 1003
  • 如果上述条件为真,则打印该行(默认操作)

awk 需要一点时间来学习;要了解它的主要内容之一是它使用成对的“模式”和“动作”语句。“模式”部分确定执行哪些“操作”语句。

您可以重写上面的 awk 以使其更加明确;通过这样做,我们可以显式打印我们想要的任何内容(例如第 5 个字段):

awk -F: '$4 == 1001 || $4 == 1003 { print $5 }'
Run Code Online (Sandbox Code Playgroud)

...或者有一个空的“模式”部分——意思是,对每一行执行“动作” ,然后在动作模式内测试值:

awk -F: '{ if ($4 == 1001 || $4 == 1003)  print $5 }'
Run Code Online (Sandbox Code Playgroud)

要强制grep采取行动,您可以执行以下操作:

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

告诉它从该行的开头查看组“任何次数的任何非冒号,后跟一个冒号”三遍,然后是 1001 或 1003,然后是冒号;打印整个匹配行,然后将其传递cut给仅打印第 5 个字段。