我正在尝试从名为 的文件中打印第四个字段值为 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正则表达式匹配这两个数字的第四个字段值(三个冒号后面的值)。非常感谢任何答案,因为从长远来看它们将帮助我解决这个问题。
答案1
在我看来,使用这样的工具会更直接awk
:
- 为您分割字段
- 准确测试您想要的字段以获得您想要的值
例如:
awk -F: '$4 == 1001 || $4 == 1003' mypasswd
...告诉 awk:
- 根据冒号将传入行拆分为字段,其中
-F:
- 使用“or”表达式来测试字段 4 的值为 1001 还是 1003
- 如果上述条件为真,则打印该行(默认操作)
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,然后是冒号;打印整个匹配行,然后将其传递给cut
仅打印第 5 个字段。
答案2
我可能会这样做sed
sed -n '/^.*:.*:.*:\(1001\|1003\):/p' mypasswd
抑制-n
行并p
在末尾打印匹配的行。
你也可以这样做grep
grep '^.*:.*:.*:1002\|1003:.*:.*:' mypasswd
答案3
正如@JeffSchaller所说,awk
这是完成这项工作的工具,因为OP希望regex
我们可以将两者结合起来
awk -F: '$4 ~ /^100[13]$/' mypasswd
grep
这允许在该版本上进行一点高尔夫推杆
grep -E "^(.*:){3}100[13]:" mypasswd
答案4
“我只需要使用egrep/grep正则表达式匹配这两个数字的第四个字段值(三个冒号后面的值)”
如果您只需要第四个字段,请cut
像grep
这样使用:
$ cat mypasswd | cut -d: -f4 | grep -E '^(1001|1003)$'
1001
1003
该grep
模式需要锚定到行的开头和结尾,否则它可能会匹配诸如 之类的数字10010
。另一种方法是grep -x -E '1001|1003'
.