在awk中使用多个定界符


202

我有一个包含以下行的文件:

/logs/tc0001/tomcat/tomcat7.1/conf/catalina.properties:app.env.server.name = demo.example.com
/logs/tc0001/tomcat/tomcat7.2/conf/catalina.properties:app.env.server.name = quest.example.com
/logs/tc0001/tomcat/tomcat7.5/conf/catalina.properties:app.env.server.name = www.example.com

在上面的输出中,我想提取3个字段(Number 2、4和最后一个*.example.com)。我得到以下输出:

cat file | awk -F'/' '{print $3 "\t" $5}'
tc0001   tomcat7.1
tc0001   tomcat7.2
tc0001   tomcat7.5

我还如何提取域名之后的最后一个字段'='?如何multiple delimiter提取字段?


2
为了回答我的相同但不同的问题,awk他们吞下了空白的字段,这模糊了字段编号。我改-F " "-F "[ ]"awk没有吞下空场了。
亚当

Answers:


324

分隔符可以是正则表达式。

awk -F'[/=]' '{print $3 "\t" $5 "\t" $8}' file

产生:

tc0001   tomcat7.1    demo.example.com  
tc0001   tomcat7.2    quest.example.com  
tc0001   tomcat7.5    www.example.com

42
当然,cat不需要过程:awk '...' file。另外,使用输出字段分隔符会更整齐:awk -F'[/=]' -v OFS="\t" '{print $3, $5, $8}'
glenn jackman

17
Awk分隔符可以是正则表达式……这让我很高兴!
das.cyklone 2014年

4
@ das.cyklone:awk也可以有几个分隔符,|例如:ex:(使用全数awk -F 'this|that|[=/]' '......' 来用单词/字符串分隔事物)(请注意,这可以使两个分隔符之间保持空格。添加也|[ \t]+可能有用,但是可以使事物棘手的...由于在“ this”之前和之后通常会有空格,因此将在空格和“ this”之间出现两个额外的空白字段)
Olivier Dulac 2014年

我已经在2个不同的发行版上尝试过此操作,并且得到了相同的行为:我想从netstat -ntpl获取端口“ netstat -ntpl | sed's /:/ /'| awk'{print $ 5}''可以,但是可以不使用doulbe管道来完成这项工作,但是我没想到字段17上的数据:“ netstat -ntpl | awk -F” |:“'{print $ 17}'”
louigi600

2
是的...这给了我我想要的东西:awk -F“ [:] +”'/ \ / postmaster * $ / {print $ 5}'
louigi600

44

好消息!awk字段分隔符可以是正则表达式。您只需要使用-F"<separator1>|<separator2>|..."

awk -F"/|=" -vOFS='\t' '{print $3, $5, $NF}' file

返回值:

tc0001  tomcat7.1  demo.example.com
tc0001  tomcat7.2  quest.example.com
tc0001  tomcat7.5  www.example.com

这里:

  • -F"/|="将输入字段分隔符设置为/=。然后,将输出字段分隔符设置为选项卡。

  • -vOFS='\t'正在使用该-v标志来设置变量。OFS是“输出字段分隔符”的默认变量,它设置为制表符。该标记是必需的,因为没有像OFS那样的内置函数-F

  • {print $3, $5, $NF} 根据输入字段分隔符打印第三,第五和最后一个字段。


参见另一个示例:

$ cat file
hello#how_are_you
i#am_very#well_thank#you

该文件有两个字段分隔符,#_。如果我们要打印第二个字段而不管分隔符是另一个还是另一个,那么让我们两个都成为分隔符!

$ awk -F"#|_" '{print $2}' file
how
am

文件编号如下:

hello#how_are_you           i#am_very#well_thank#you
^^^^^ ^^^ ^^^ ^^^           ^ ^^ ^^^^ ^^^^ ^^^^^ ^^^
  1    2   3   4            1  2   3    4    5    6

1
感谢@BUFU进行编辑。我删除了OFS参考,只专注于FS部分,但是拥有它也很好。干杯!
fedorqui'SO停止伤害'

5

如果您的空格是一致的,则可以将其用作分隔符,而不是\t直接插入,而可以设置输出分隔符,它将自动包括在内:

< file awk -v OFS='\t' -v FS='[/ ]' '{print $3, $5, $NF}'

3

对于2通过数字,5字母a#空格分隔的字段分隔符,分隔符必须重复至少2次且不超过6次,例如:

awk -F'[2-5a# ]{2,6}' ...

我确定使用()和参数会存在这种变化


3

Perl一线:

perl -F'/[\/=]/' -lane 'print "$F[2]\t$F[4]\t$F[7]"' file

这些命令行选项用于:

  • -n循环输入文件的每一行,将其放入$_变量中,不要自动打印每一行

  • -l 在处理之前删除换行符,然后再将其重新添加

  • -a自动拆分模式– perl将自动将输入行拆分为@F阵列。默认为在空白处分割

  • -F自动拆分修饰符,在此示例中拆分为/=

  • -e 执行Perl代码

Perl与awk密切相关,但是,自动@F拆分数组从index开始,$F[0]而awk字段从$ 1开始。


2

另一种方法是使用-F选项,但将其传递给regex来在左右括号之间打印文本()

文件内容:

528(smbw)
529(smbt)
530(smbn)
10115(smbs)

命令:

awk -F"[()]" '{print $2}' filename

结果:

smbw
smbt
smbn
smbs

使用awk仅打印之间的文本[]

使用awk -F'[][]'awk -F'[[]]'不起作用。

http://stanlo45.blogspot.com/2020/06/awk-multiple-field-separators.html


您的答案出现在删除队列中,因为10个问题中有9个(具有1个声誉的用户链接到自己的博客)通常是垃圾邮件。但是您是该规则的例外。最近十年的内容中有一座金矿,希望您有一个使之永生的计划。
埃里克·莱斯钦斯基

0

我看到板上有很多完美的答案,但是仍然想上传我的代码,

awk -F"/" '{print $3 " " $5 " " $7}' sam | sed 's/ cat.* =//g'


2
print $3 " " $5 " " $7可以像一样打印print $3, $5, $7。另外,我没有看到使用awk然后通过管道传输到sed的优势。通常,awk就足够了,其他人的回答表明了这一点。
fedorqui'SO停止伤害
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.