2017-03-01 43 views
0

我是shell脚本中的新手。我有一个要求,用“;”分隔具有特殊字符和空格的输入文件的文件字段。如何分隔具有特殊字符的输入文件的字段?

输入文件:

---------------------------------- 
Server     Port 
---------------------------------- 
Local      1001 

----------------------------------------- 
Name  Country  Count 
----------------------------------------- 
XXX   Bermuda  999 

所以,我的要求是让输出一样,

输出:

Server;Port;Name;Country;Count 
Local;1001;XXX;Bermuda;999 

请帮我实现这个要求。 我喜欢的任何工具,无论是AWK,sed的,等等,我不想虚线

+0

是总的文件? – dawg

+0

是的,它是完整的文件 –

+3

有多少变化?你可以在国名(沙特阿拉伯)有两个字吗?可以有两组以上的行吗?数据可以是单个字段吗?编写能够处理该文件的代码很容易;问题是 - 它还应该处理哪些其他文件? –

回答

0

要开始,

  1. 在他们sed删除空白行或有。如果您的文件与示例的布局完全相同,则会导致奇数行上的标题行和偶数行上的数据行。
  2. 使用POSIX实用程序获取该文件unexpand该terns将空格运行为选项卡,但只留下单个空格。 (如果该文件已经TSV这不是必需的。)
  3. 使用awk到entabbed文件现在处理成由;

演示分离的标题行和数据行:

sed -E '/^--*$|^$/d' file | unexpand -a | awk 'BEGIN{FS="\t"} 
                NR%2 {for (i=1;i<=NF;i++) { 
                   gsub(/^[ ]+/,"",$i) 
                   h=h ? h ";" $i : $i ";" } 
                   next} 
                  {for (i=1;i<=NF;i++) { 
                   gsub(/^[ ]+/,"",$i) 
                   b=b ? b ";" $i : $i ";" } 
                   }  
                END{print h 
                 print b}' 

打印:

Server;;;;Port;Name;Country;Count 
Local;;;;1001;XXX;Bermuda;999 

这将支持空间数据领域,比如“沙特”

+0

谢谢,它的作品 –

0

只有Awk。它假定分隔符是两个或两个以上的空间,这样多的名称,如Ber muda可能是可能的:

$ awk 'BEGIN{ 
     FS=" +";   # delimiter is two or more spaces 
     OFS=";"    # output delimiter 
    } 
    /^-*$/ { next }   # dashed or empty records are discarded 
    { 
     $1=$1;    # rebuild records to change delimiters 
     if(/^Server|^Name/) # gather header 
      h=h $0 OFS; 
     else     # gather data 
      d=d $0 OFS 
    } 
    END {     # print header and data record 
     print h; 
     print d 
    }' file 
Server;Port;Name;Country;Count; 
Local;1001;XXX;Ber muda;999; 

缺点是尾随OFS但是,人们可以与一对夫妇的sub s内删除。

1

另一种解决方案,使用sedawk

sed -E '/^-/d;/^$/d;s/[[:space:]]+/;/g' file | 
awk '{d[NR%2]=(d[NR%2]?d[NR%2]";":"")$0}END{print d[1]; print d[0]}' 

awk

awk '/^-/ || !NF{next}{ 
    gsub(/[[:space:]]+/,";") 
    d[i%2]=(d[i%2]?d[i%2]";":"")$0 
    ++i 
}END{print d[0]; print d[1]}' file 

你,

Server;Port;Name;Country;Count 
Local;1001;XXX;Bermuda;999 

编辑:与输入型john smithSaudi Arabia

​​

可以使用[[:space:]][[:space:]]+代替[[:space:]]+

你,

 
Server;Port;Name;Country;Count 
Local;1001;john smith;Saudi Arabia;999 
+0

这是最好的解决方案,只要名称中没有空格,沙特阿拉伯' – dawg

+0

@dawg只使用'[[:space:]] [[:space:]] +'而不是'[[:space:]] +' –

相关问题