假设我的文本文件包含:
101 Adam
201 Clarie
502 Adam
403 Tom
我想在 shell 中编写一个命令,只给我基于特定名称的数字。例如,仅输出名称“Adam”的数字将给出:
101
502
我在想这样的事情:
cut -f 1 Data_1 | grep "Adam"
但它不起作用。 Data_1 是文件名。 1 指第一列。我是 Unix 新手,所以我会很感激对此的一些反馈。
答案1
您可以grep
通过选项将 single 与 perl 环视扩展一起使用-P
:
grep -Po '.*(?=Adam)' file
这将打印一行中直到单词 Adam 的所有内容。
如果您只想要数字,不包括空格等,那么:
grep -Po '[0-9]*(?=.*Adam)' file
答案2
建议用于awk
此
- 默认输入字段分隔符是一个或多个连续的空格,因此无需担心空格/制表符分隔
- 更容易比较固定字符串(即不太容易出现正则表达式元字符 - 在使用引号和反斜杠字符构造字符串时需要小心。另请参阅转义序列)
$ cat ip.txt
101 Adam
201 Clarie
502 Adam
403 Tom
$ # check if 2nd column value is Adam (wont match MAdam, Adama, etc)
$ # use $NF instead of $2 to check against last column
$ awk '$2=="Adam"{print $1}' ip.txt
101
502
$ # using variable instead of string constant
$ awk -v name='Adam' '$2==name{print $1}' ip.txt
101
502
$ # passing shell variable
$ n='Tom'
$ awk -v name="$n" '$2==name{print $1}' ip.txt
403
答案3
首先你有 grep/cut 向后的顺序。而且,除非这些是分隔列的实际制表符(如Tab)(我无法告诉),否则您还需要指定正常的空白(如Space)是您的分隔符。
grep Adam Data_1 | cut -f1 -d' '
如果您使用制表符,请不要使用-d' '
。
一般来说,在构建这样的复合命令时一次尝试一件事。当你独自一人做事时,你会看到什么cut
?看起来应用grep
它有意义吗?如果没有,那就重新考虑一下。
和总是man
仔细阅读每个命令的页面。
奖金:这是sed
执行相同操作的命令:
sed -n 's/^\(.*\)\t\+Adam$/\1/p' Data_1
这会遍历文件中的每一行,但仅打印以一个或多个选项卡和搜索字符串结尾的行。然后,在打印之前,它会删除那些相同的选项卡和搜索字符串。
答案4
使用 Awk 的简单方法:
awk '/ Adam$/ {print $1}' file
101
502