使用unix工具进行文本处理

使用unix工具进行文本处理

我有一个以下格式的文件。

abc|xyz|mno  
x up x  
up up x  
x x up  

abc|xyz|mno  
x x x  
up x x  

....  
....

基本上,文件的第一行是设备名称(|ed),接下来的行是设备的状态。

我希望输出采用以下格式:

abc,x|xyz,up|mno,x  
abc,up|xyz,up|mno,x  
abc,x|xyz,x|mno,up  

abc,x|xyz,x|mno,x  
abc,up|xyz,x|mno,x  

....  
....  

你有什么指点吗?

答案1

如果您可以将perl, 与List::MoreUtilsCPAN 中的模块一起使用:

$ perl -MList::MoreUtils=pairwise -F'\|' -anle '
    print and next if /^$/;
    @dev = @F and next if @F > 1;
    print join "|", pairwise {"$a,$b"} @dev,@{[split]};
' file
abc,x|xyz,up|mno,x
abc,up|xyz,up|mno,x
abc,x|xyz,x|mno,up

abc,x|xyz,x|mno,x
abc,up|xyz,x|mno,x

如果您不喜欢使用外部模块:

$ perl -F'\|' -anle '
    print and next if /^$/;
    @dev = @F and next if @F > 1;
    @state = split;
    print join "|", map {"$dev[$_],$state[$_]"} 0..$#dev;
' file

答案2

awk如果输入与描述完全相同,以下命令应该执行您想要的操作(但它不执行任何错误检查):

awk '/\|/ {split($0, devices, "|"); next} /^$/ {print; next}
    {for (i=1; i<NF; i++) printf "%s,%s|", devices[i], $i; printf "%s,%s\n", devices[NF], $NF}'
  • 如果输入行包含 a |,则在|s 处将其拆分为一个名为“devices”的数组。 (我们需要使用,\|因为普通|意味着或者,如/cat|dog/。)然后继续执行next输入数据行(即,不执行以下命令)。
  • 如果输入行为空,则打印它(空行)并继续到下一行,而不执行以下命令。
  • 对于与上述之一不匹配的每一行,对于每个字段最多但不包括最后,打印相应的设备名称和换行符,|但不包含换行符。然后用换行符打印最后一个字段,但不打印|

相关内容