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

reformatting text file from rows to column

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

========================================================
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。

谢谢

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

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

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

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

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

  1. 以既不包含 : 也不包含 = 字符([^:=]\+ 部分)的子字符串开始;
  2. 然后跟:=和任意数量的空格([:=] *部分);
  3. 最后,以任意子字符串结束(*\(.*\) 部分)。

然后捕获并打印最后一个子字符串,而不是原始字符串。输入文件中的任何其他行都将被丢弃。

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

我们需要将 mapfile 包裹在子外壳中的原因解释如下:readarray (or pipe) issue.