【问题标题】:parse a text file in shell scripting在 shell 脚本中解析文本文件
【发布时间】:2016-01-04 07:41:06
【问题描述】:

我想读取一个文件并使用 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

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

【问题讨论】:

  • 您能说得更具体一点吗?在您的标题中,您正在寻求使用 shell 编程的解决方案,但随后您寻求 awk 程序的帮助。此外,尚不清楚您的问题到底出在哪里。首先我想,你在收集属于一个主机的行时遇到问题,但后来你明确提到了rsplit。你到底需要知道什么?如何在awk中实现rsplit?如果是,您使用的是哪个 awk(旧 awk、gawk、....)?

标签: shell awk sh


【解决方案1】:

由于您没有在问题中提到您的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,打印1st2nd 字段,由:space 分隔。继续此操作,直到我们遇到 end 模式 (/end/),我们将在此处打印新行。

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

【讨论】:

  • 非常感谢它帮助了我如果我只想从这个文件中打印一个块,比如牛,我可以使用什么 awk 命令?
  • Arash Shams : awk '/#begin cow/{v=1}!/^#/&&v{printf $1": "$2" "}/end/&&v{print '\n'; v=0}' 文件。如果有帮助,您可以投票并接受答案。
  • 我决定删除 #begin 和 #end 那么我如何更改命令以从主机的开头解析到另一个主机的开头意味着像 Host dns2 HostName 172.20.4.80 User root Port 这样的块22
【解决方案2】:

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

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

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

与过滤器相同(仅在过滤器相同时打印;这里如果主机是 cowboy

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 时,如果第二个单词包含/对应于Filter 变量(在这种情况下为^cow$|^boy$)的正则表达式,则变量PassFilter 设置为true。
  • {Infos = Infos ($1~/^Host$/ ? "" : Sep) $1 ": " $2} 将当前行的内容(第一个 ($1) 然后 : 最后是第二个单词)添加到变量 Infos 中,并使用分隔符 if not line withHost` 作为第一个单词。

【讨论】:

  • 谢谢它非常有帮助,但我如何控制参数之间的选项卡
  • 如果我只想从这个文件中打印一个块,比如牛,我可以使用什么 awk 命令?
  • 您需要在 block 上添加一个过滤器。在这种结构中最好在打印之前。 2选择,过滤块或中块。我在块内展示样本(易于适应)
  • 你能给我一个样品吗?我可以弄清楚
  • 附上一些基本解释
猜你喜欢
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 2012-07-10
  • 2013-11-27
  • 2014-04-28
  • 2014-05-06
  • 1970-01-01
相关资源
最近更新 更多