繁体   English   中英

使用awk打印一段文本,直到第一个空白行

[英]Print a block of text until the first blank line using awk

这是我的示例文件:

Host dns2
        HostName 172.20.4.80
        User root
        Port 22

Host dns1
        HostName 172.20.4.75
        User root
        Port 22

Host dns3
        HostName 172.20.4.76
        User root
        Port 22

Host dns4
        HostName 172.20.4.77
        User root
        Port 22

Host dns5
        HostName 172.20.4.78
        User root
        Port 22

Host dns6
        HostName 172.20.4.79
        User root
        Port 22

例如,我只想打印一个块

Host dns1
        HostName 172.20.4.75
        User root
        Port 22

输出:

Host: dns2  HostName: 172.20.4.80   User: root  Port: 22

但在此示例中,所有块都有4行,也许以后它们会达到5行或更多行,所以我想从主机打印到第一行或从主机删除到第一行

我真的对正则表达式不好,需要这个来完成我的脚本

谢谢

我认为您基本上想要这样:

awk -v RS='' '/dns1/' file

取消设置记录分隔符,以便将每个块都视为一条记录,然后打印与模式匹配的任何记录。

或使用shell变量:

host=dns1
awk -v host="$host" -v RS='' '$0 ~ host' file

在这两个示例中,我都使用默认操作为{ print }的事实。 由于您可能会使用{ printf ... }来更改输出,因此您可能要考虑添加一个exit语句,以避免不必要地处理文件的其余部分。

类似的awk

$ awk -v RS= -v OFS=' ' '{for(i=1;i<NF;i+=2) $i=$i":"}1' hosts

Host: dns2 HostName: 172.20.4.80 User: root Port: 22
Host: dns1 HostName: 172.20.4.75 User: root Port: 22
Host: dns3 HostName: 172.20.4.76 User: root Port: 22
Host: dns4 HostName: 172.20.4.77 User: root Port: 22
Host: dns5 HostName: 172.20.4.78 User: root Port: 22
Host: dns6 HostName: 172.20.4.79 User: root Port: 22

将以所需的输出格式为您提供所有记录。 您可以进一步过滤此输出,也可以添加诸如

$ awk -v RS= -v OFS=' ' '{for(i=1;i<NF;i+=2) $i=$i":"} /dns2/' hosts

Host: dns2 HostName: 172.20.4.80 User: root Port: 22

如果要在处理所选记录后退出,则需要稍微更改脚本

$ awk -v RS= -v OFS=' ' '/dns2/{for(i=1;i<NF;i+=2) $i=$i":"; print; exit}' hosts
Host: dns2 HostName: 172.20.4.80 User: root Port: 22

如果要选择除一条记录以外的所有内容,则可以取反模式(并删除退出)

$ awk -v RS= -v OFS=' ' '!/dns2/{for(i=1;i<NF;i+=2) $i=$i":"; print}' hosts
Host: dns1 HostName: 172.20.4.75 User: root Port: 22
Host: dns3 HostName: 172.20.4.76 User: root Port: 22
Host: dns4 HostName: 172.20.4.77 User: root Port: 22
Host: dns5 HostName: 172.20.4.78 User: root Port: 22
Host: dns6 HostName: 172.20.4.79 User: root Port: 22

请注意,sed就地替换需要一个中间文件。 如果要将原始文件替换为无一个记录的格式化文件,则可以在最后一个awk语句上使用此命令模式

$ awk ... > temp && mv temp original

更新:设置OFS将更改字段之间的所有分隔符。 您想按name: value逻辑对它们进行分组name: value ,因此将脚本更改为

$ awk -v RS= '{for(i=1;i<NF;i++) $i=$i (i%2?":":"\t")}1' hosts
Host: dns2       HostName: 172.20.4.80   User: root      Port: 22
Host: dns1       HostName: 172.20.4.75   User: root      Port: 22
Host: dns3       HostName: 172.20.4.76   User: root      Port: 22
Host: dns4       HostName: 172.20.4.77   User: root      Port: 22
Host: dns5       HostName: 172.20.4.78   User: root      Port: 22
Host: dns6       HostName: 172.20.4.79   User: root      Port: 22

在偶数定位的字段之后设置制表符分隔符。

与Tom Fenech的方法没有什么不同,因为它使用记录分隔符,但是它也与字段分隔符一起使用以获得所需的输出:

awk -v RS='' -F'\n[\t ]*' -v OFS='  ' '/dns1/{$1=$1;print}' file

更改输出字段分隔符时,需要使用$1=$1 (或$0=$0或与任何其他字段一起使用)强制awk重新评估记录并考虑新的字段分隔符。

注意:使用exit命令找到匹配的块时,可以退出awk。 这样可以避免处理文件的所有结尾。 您也只能使用第一个字段测试模式/dns1/

awk -v RS='' -F'\n[\t ]*' -v OFS='  ' '$1~/dns1/{$1=$1;print;exit}' file

如果在结果中添加分号,则由于您修改了字段,因此$1=$1技巧将变得无用。 你可以写:

awk -v RS='' -F'\n[\t ]*' -v OFS='  ' '$1~/dns1/{for(i=1;i<=NF;i++){sub(" ", ": ", $i)};print;exit}' file

要打印第三条记录:

$ awk -v RS= -F'\n[[:blank:]]+' -v OFS='\t' 'NR==3{$1=$1; gsub(/ +/,": "); print}' file
Host: dns3      HostName: 172.20.4.76   User: root      Port: 22

要打印包含dns4的记录:

$ awk -v RS= -F'\n[[:blank:]]+' -v OFS='\t' '/dns4/{$1=$1; gsub(/ +/,": "); print}' file
Host: dns4      HostName: 172.20.4.77   User: root      Port: 22

要打印所有包含dns3dns4dns5记录,请dns4以下dns5

$ awk -v RS= -F'\n[[:blank:]]+' -v OFS='\t' '!/dns[345]/{$1=$1; gsub(/ +/,": "); print}' file
Host: dns2      HostName: 172.20.4.80   User: root      Port: 22
Host: dns1      HostName: 172.20.4.75   User: root      Port: 22
Host: dns6      HostName: 172.20.4.79   User: root      Port: 22

这可能对您有用(GNU sed):

 sed -n '/Host dns1/{:a;N;/^\s*$/M!ba;s/\n\s*/  /g;s/\s*$//p}' file

这将重点放在所需的字符串上,然后追加以下几行直到空白为止,最后操作收集到所需输出中的新字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM