将文本文件从行重新格式化为列

时间:2016-11-24 10:35:15

标签: bash shell centos7

我在目录中有多个文件需要重新格式化并将输出放在一个文件中,文件结构为:

========================================================
Daily KPIs  -   DATE:  24/04/2013
========================================================

--------------------------------------------------------
Number of des         =  5270
--------------------------------------------------------
Number of users       =  210
--------------------------------------------------------
Number of active      =  520
--------------------------------------------------------
Total non             =  713
--------------------------------------------------------

========================================================

我需要输出格式为:

Date,Numberofdes,Numberofusers,Numberofactive,Totalnon
24042013,5270,210,520,713

该目录包含大约1500个具有相同格式的文件,我使用Centos 7。

由于

1 个答案:

答案 0 :(得分:1)

首先我们需要一个方法将数组的元素连接成一个字符串( cf。 Join elements of an array?):

function join_array()
{
    local IFS=$1
    shift
    echo "$*"
}

然后我们可以遍历每个文件并将每个文件转换为以逗号分隔的列表(假设原始文件的名称以*.txt结尾)。

for f in *.txt
do
    sed -n 's/[^:=]\+[:=] *\(.*\)/\1/p' < $f | {
        mapfile -t fields
        join_array , "${fields[@]}"
    }
done

这里,sed命令在每个输入文件中查找以下行:

  1. 以不包含:=字符([^:=]\+部分)的子字符串开头;
  2. 然后关注:=以及任意数量的空格([:=] *部分);
  3. 最后,以任意子串(*\(.*\)部分)结束。
  4. 然后捕获并打印最后一个子字符串而不是原始字符串。输入文件中的任何其他行都将被丢弃。

    之后,sed的输出被mapfile读入索引数组变量fields-t确保丢弃每行读取的尾随换行符)最后通过我们之前定义的join_array方法连接线。

    我们需要在子shell中包装mapfile的原因在这里解释:readarray (or pipe) issue