在 shell 脚本中解析文本文件

parse a text file in shell scripting

我想读取文件并使用 shellscript 将其打印到标准输出。在 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

任何人都可以帮助我解决这个问题 谢谢

由于您没有在问题中提及 awk 命令,我假设您正在寻找具有 awk 和解释的解决方案。

AMD$ awk '!/^#/{printf ": "" "}/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 (!/^#/),打印 1st2nd: 和分隔的字段space。继续此操作,直到我们达到 end 模式 (/end/),我们将在此处打印新行。

如果您正在寻找对您已有的 awk 命令的解释,请在问题中提及。

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

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

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

与过滤器相同(仅当过滤器相同时打印;此处如果主机是 cowboy

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

解释:

  • /^#begin/{Infos="";next} 重置字符串以打印以 `#begin 开头的每一行,转到源文件的下一行(不要处理以下指令)。
  • /^#end/&&PassFilter{print Infos;next} 当行以#end开始且变量PassFilter为真(=1)时,打印Infos的字符串内容,转到下一行源文件。
  • ~/^Host$/{PassFilter=~Filter} 当行第一个词是 Host 时,如果第二个词 contains/corresponds 到 Filter 变量,则变量 PassFilter 设置为真(^cow$|^boy$ 在这种情况下)。
  • {Infos = Infos (~/^Host$/ ? "" : Sep) ": " } 将当前行的内容(首先是 (</code>) 然后是 <code>: 最后是第二个单词)添加到变量 Infos 中,使用分隔符 if not line withHost` 作为第一个词。