解析shell脚本中的文本文件

时间:2016-01-04 07:41:07

标签: shell awk sh

我想读取一个文件并使用shellscript将其打印到stdout。在python rsplit可以完成这项工作但我搜索并找到awk但我无法理解。

文件1:

#begin cow
Host cow
    HostName 172.18.0.10
    User root
    Port 22
#end cow
#begin dns2
Host dns2
    HostName 172.20.4.80
    User root
    Port 22
#end dns2
#begin dns1
Host dns1
    HostName 172.20.4.75
    User root
    Port 22
#end dns1
#begin dns3
Host dns3
        HostName 172.20.4.76
        User root
        Port 22
#end dns3
#begin dns4
Host dns4
        HostName 172.20.4.77
        User root
        Port 22
#end dns4
#begin dns5
Host dns5
        HostName 172.20.4.78
        User root
        Port 22
#end dns5
#begin dns6
Host dns6
        HostName 172.20.4.79
        User root
        Port 22
#end dns6

解析后转到

Host: cow  Hostname: 172.18.0.10 User: root Port: 22
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

任何人都可以帮助我 谢谢

2 个答案:

答案 0 :(得分:5)

由于您未在问题中提及awk命令,因此我假设您正在寻找包含awk的解决方案及解释。

AMD$ awk '!/^#/{printf $1": "$2" "}/end/{print '\n'}' File

Host: cow HostName: 172.18.0.10 User: root Port: 22
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

对于以NOT#)开头的所有行!/^#/,打印由1st和{{分隔的2nd:字段1}}。继续这样做,直到我们点击space模式(end),我们将在那里打印新行。

如果您要查找已有/end/命令的说明,请在问题中提及。

答案 1 :(得分:2)

根据您的文字(假设结构已完成(开始 - >结束),没有空行,...)

awk -v "Sep=\t" '/^#begin/{Infos="";next}/^#end/{print Infos;next}{Infos = Infos ($1~/^Host$/ ? "" : Sep) $1 ": " $2}' YourFile

Sep是info子序列之间的分隔符。

与过滤器相同(仅在过滤器相同时打印;此处如果主机是 cow boy

awk -v "Sep=\t" -v"Filter=^cow$|^boy$" '
   /^#begin/{Infos="";PassFilter=0;next}
   /^#end/&&PassFilter{print Infos;next}
   $1~/^Host$/{PassFilter=$2~Filter}
   {Infos = Infos ($1~/^Host$/ ? "" : Sep) $1 ": " $2}
   ' YourFile

<强>解释

  • /^#begin/{Infos="";next}重置字符串以打印以#begin开头的每一行,转到源文件的下一行(不要处理以下指令)。
  • /^#end/&&PassFilter{print Infos;next}当行开头为#end且变量PassFilter为真(= 1)时,打印Infos的字符串内容,转到源文件的下一行
  • $1~/^Host$/{PassFilter=$2~Filter}当第一个单词为Host时,如果第二个单词包含/对应于正则表达式PassFilter变量{{1},则变量Filter设置为true在这种情况下)。
  • ^cow$|^boy$使用分隔符{{1}将当前行的内容(第一个({Infos = Infos ($1~/^Host$/ ? "" : Sep) $1 ": " $2}),然后$1,最后是第二个字实际上)添加到变量: } Host`作为第一个单词。