合并BASH中的文件的常见部分

时间:2014-03-15 15:28:20

标签: arrays bash sed awk merge

我一直试图找到一种方法以某种方式合并三个文件在每个文件的公共点,我想我会请求一些帮助。我的搜索让我参观了从sed和awk到数组的许多可能的解决方案。 router.txt文件是框架文件,我想在vars.txt和cleanup.txt中读取,以生成包含每个部分内容的单个文件。合并的文件应包含每个文件的每个部分中包含所有相关数据的所有部分。

我已尝试使用以下数组:

rtimeserver=(`sed -n "/TIME SERVER/,/! -/p" router.txt | sed '/! -/{2,$d}' `)  
vtimeserver=(`sed -n "/TIME SERVER/,/! -/p" vars.txt | sed '/! -/{2,$d}' `)  
cleantimeserver=(`sed -n "/TIME SERVER/,/! -/p" cleanup.txt | sed '/! -/{2,$d}' `)  

通过以下内容,我只能打印出我想要的每个文件的部分。

 printf "%s\n" "${rtimeserver[@]}"  
 printf "%s\n" "${vtimeserver[@]}"  
 printf "%s\n" "${cleantimeserver[@]}"  

但我看不出能够弄清楚如何在路由器文件中找到该部分并在其他文件的部分中滑动。我以为我可以使用SED的搜索功能找到该部分并转储数组内容,但我需要帮助。

我非常感谢您愿意提供的任何帮助 提前谢谢,
迈克

router.txt

  !  
  ! ---- NAME SERVER ----  

  ! ---- TIME SERVER ----  
  ntp trusted-key  
  ntp authenticate  
  ntp source Loopback0  
  ! ---- TACACS CONFIG ----  
  !  
  ip tacacs source-interface Loopback 0  
  tacacs-server retransmit 2  
  tacacs-server timeout 2  
  no tacacs-server directed-request  

vars.txt

  ! ---- NAME SERVER ----  
  no ip name-server  
  ip domain-name lab.com  
  ip domain name lab.com  
  ip domain-list lab.com  
  ip domain-list int.lab.com  
  ! ---- TIME SERVER ----  
  ntp server 1.1.1.1  
  sntp server 2.2.2.2  
  ! ---- TACACS CONFIG ----  
  tacacs-server key 1111111111  
  tacacs-server host 1.1.1.1  
  tacacs-server host 1.1.1.2  

cleanup.txt

  ! ---- NAME SERVER ----  
  no ip dns server-address 3.3.3.3  
  no ip dns server-address 3.3.3.4  
  no ip dns server-address 3.3.3.5  
  ! ---- TIME SERVER ----  
  no clock summer-time  
  sntp poll-interval 65535  
  clock timezone gmt GMT+00  
  ip sntp source-interface loopback 1  
  ! ---- TACACS CONFIG ----  
  tacacs-server host 3.3.3.3  
  tacacs-server host 3.3.3.4  
  tacacs-server host 3.3.3.5  

merged.txt

  ! ---- TIME SERVER ----  
  ntp trusted-key  
  ntp authenticate  
  ntp source Loopback0  
  ntp server 1.1.1.1  
  sntp server 2.2.2.2  
  no clock summer-time  
  sntp poll-interval 65535  
  clock timezone gmt GMT+00  
  ip sntp source-interface loopback 1  

2 个答案:

答案 0 :(得分:1)

提示:

awk '
/! ---/ { p = 0 }        # Disable the flag if lines with header text is seen
p { lines[++l] = $0 }    # If flag is enabled, populate an array with that line
/TIME SERVER/ { header = $0; p = 1 }  # Enable the flag when the line with TIME SERVER is seen and capture the line in header variable
END { 
    print header > "merged.txt"            # Print your header in a new file
    for(line = 1; line <= l; line++)       # Iterate over the array
        print lines[line] >"merged.txt"    # Printing each line in a new file
}' router.txt vars.txt cleanup.txt

解决方案:

扩展上面给出的提示,您可以执行以下操作来捕获所有内容:

awk '
/! -/ { p = 0 }
    p { lines[seen] = lines[seen] RS $0 }
/! -/ { seen = $0 ; p = 1}
END {
    for (line in lines)
        print line, lines[line] > "merged.txt"
}' router.txt vars.txt cleanup.txt

这会创建一个名为merged.txt的新文件,如下所示:

$ cat merged.txt
! ---- NAME SERVER ----

no ip name-server
ip domain-name lab.com
ip domain name lab.com
ip domain-list lab.com
ip domain-list int.lab.com
no ip dns server-address 3.3.3.3
no ip dns server-address 3.3.3.4
no ip dns server-address 3.3.3.5
! ---- TIME SERVER ----
ntp trusted-key
ntp authenticate
ntp source Loopback0
ntp server 1.1.1.1
sntp server 2.2.2.2
no clock summer-time
sntp poll-interval 65535
clock timezone gmt GMT+00
ip sntp source-interface loopback 1
! ---- TACACS CONFIG ----
!
ip tacacs source-interface Loopback 0
tacacs-server retransmit 2
tacacs-server timeout 2
no tacacs-server directed-request
tacacs-server key 1111111111
tacacs-server host 1.1.1.1
tacacs-server host 1.1.1.2
tacacs-server host 3.3.3.3
tacacs-server host 3.3.3.4
tacacs-server host 3.3.3.5

<强>更新

要保留第一个文件的顺序,您可以执行以下操作:

awk '
/! -/ { p = 0 }
    p { lines[seen] = lines[seen] RS $0 }
/! -/ { !($0 in head) ? header[++i]=$0 : x ; p = 1; head[$0]++; seen = $0}
END {
    for (a=1; a<=i; a++)
        print a, header[a], lines[header[a]]
}' router.txt vars.txt cleanup.txt

答案 1 :(得分:0)

使用awk

awk 'BEGIN{print "! ---- TIME SERVER ---- "}
/TIME SERVER/{for (i=2;i<NF;i++) print $i}' FS="\n" RS="! ----" router.txt vars.txt cleanup.txt

! ---- TIME SERVER ---- 
  ntp trusted-key  
  ntp authenticate  
  ntp source Loopback0  
  ntp server 1.1.1.1  
  sntp server 2.2.2.2  
  no clock summer-time  
  sntp poll-interval 65535  
  clock timezone gmt GMT+00  
  ip sntp source-interface loopback 1

解释

  • FS="\n" RS="! ----"这些是这个awk命令的关键点,正确定义RS和FS以简化过程。