我需要帮助来处理一个命令,它是一个*
(星)分隔文件有多行,如下所述。我想搜索以NM1*IL
开头并提取最后一列的行。以下是显示的示例。
$ cat temp.txt
NM1*IL*1*RESTAR*FRENNY*M***MI*99358358~
N3*2164 Boeing Avenue~
N4*NEW DELHI*CA*94114~
DMG*D0*19550610*F~
NM1*PR*2*KFHP*****PI*94135~
NM1*IL*1*STAR*FRENY*M***MI*99358958~
NM1*IL*1*RESTA*ANNIE*M***MI*993583589~
我想要输出如下
99358358
99358958
993583589
grep 'NM1[*]IL' temp.txt | awk -F'*' '{print $NF}' | sed 's/~$//'
您可以运行此管道的一部分(最多但不包括|
)以查看特定命令对您的输入执行的操作。
grep 'NM1[*]IL'
- 过滤输入行,以便只留下与此模式匹配的输入行。 grep
将正则表达式作为其参数,*
是一个特殊的正则表达式字符(表示它所遵循的符号的0或更多),因此它需要转义。我在这里使用了一个角色类([]
),因为我觉得它很整洁。可以使用NM1\*IL
达到同样的效果。
awk -F'*'
- -F
指定字段分隔符,我将其设置为*
。 Awk将每个输入行拆分为字段,因此两个*
s之间的任何内容都是awk的字段。
'{print $NF}'
是它现在将在其输入上执行的awk程序。它说“对于所有输入行打印带有数字NF
的字段”,其中NF
是一个特殊的awk变量,它代表“字段数”。所以它的作用是打印最后一个字段。
sed 's/~$//'
- 只是剥离落后的~
。 $
意味着行尾。所以这个sed用空字符串替换EOL之前的任何tildas。可以写tr -d '~'
,但这个sed更精确(只在EOL之前剥离tildas)。
grep(1)
,awk(1p)
和sed(1)
都是标准的UNIX命令行实用程序。研究手册页以获取有关如何使用它们的更多信息。
由于您的问题被标记为linux
,我假设您使用的是GNU grep:
$ grep -oP '^NM1\*IL.*\*\K.*(?=~)' /tmp/file
99358358
99358958
993583589
这是使用带有后视和前瞻零宽度断言的pcre
语法 - 当使用\K
选项时,匹配到(?=...)
和-o
内部的东西将不会包含在输出中。