Unix将行转换为列

时间:2018-08-10 13:59:38

标签: bash unix awk sed

我有一个程序需要转换为列的输出。 我知道您可以使用awk或sed来执行此操作,但是我似乎不知道如何操作。

这是输出的样子:

insert_job: aaa-bbb-ess-qqqqqqq-aaaaaa-aaaaaa   job_type: c
box_name: sss-eee-ess-saturday
command: $${qqqq-eee-eat-cmd} $${qqqq-eee-nas-cntrl-dir}\eee\CMS\CMS_C3.xml $${qqqq-eee-nas-log}\eee\AFG\AFG_Build_Qwer.log buildProcess
machine: qqqq-eee-cntl
owner: system_uu_gggg_p@ad
permission: gx,wx
condition: s(qqqq-rtl-etl-40-datamart-load-cms) & s(qqqq-eee-ess)
std_out_file: >E\:\gggg\logs\qqqq-eee-ess-saturday-cms-build.out
std_err_file: >E\:\gggg\logs\qqqq-eee-ess-saturday-cms-build.err
max_run_alarm: 420
alarm_if_fail: 1
application: qqqq-M9887

我需要它看起来像这样 I need it to look like this

或者这样:

insert_job:                 job_type:   box_name:       command:        machine: 
aaa-bbb-ess-qqqqqqq-aaaaaa-aaaaaa   c       sss-eee-ess-saturday    $${qqqq-eee-eat-cmd}    qqqq-eee-cntl

insert_job:;job_type:;box_name:;command:;machine:; 
aaa-bbb-ess-qqqqqqq-aaaaaa-aaaaaa;c;sss-eee-ess-saturday;$${qqqq-eee-eat-cmd};qqqq-eee-cntl;

基本上或者已经使用TAB分隔或采用CSV格式。 感谢您的帮助

2 个答案:

答案 0 :(得分:1)

您没有向我们展示实际的预期输出是什么样子,因此我假设您希望将其制表符分隔和不加引号,并且对输入记录的分隔方式进行了其他一些假设,等等:

$ cat tst.awk
BEGIN { OFS="\t" }
{
    if ( numTags == 0 ) {
        tag = $1
        val = $2
        sub(/:$/,"",tag)
        tags[++numTags] = tag
        tag2val[tag] = val
        sub(/[^:]+: +[^ ]+ +/,"")
    }
    tag = val = $0
    sub(/: .*/,"",tag)
    sub(/[^:]+: /,"",val)
    tags[++numTags] = tag
    tag2val[tag] = val
}
tag == "application" {
    if ( !cnt++ ) {
        for (tagNr=1; tagNr<=numTags; tagNr++ ) {
            tag = tags[tagNr]
            printf "%s%s", tag, (tagNr<numTags ? OFS : ORS)
        }
    }
    for (tagNr=1; tagNr<=numTags; tagNr++ ) {
        tag = tags[tagNr]
        val = tag2val[tag]
        printf "%s%s", val, (tagNr<numTags ? OFS : ORS)
    }
    numTags = 0
}

$ awk -f tst.awk file
insert_job      job_type        box_name        command machine owner   permission      condition       std_out_file    std_err_file    max_run_alarm   alarm_if_fail   application
aaa-bbb-ess-qqqqqqq-aaaaaa-aaaaaa       c       sss-eee-ess-saturday    $${qqqq-eee-eat-cmd} $${qqqq-eee-nas-cntrl-dir}\eee\CMS\CMS_C3.xml $${qqqq-eee-nas-log}\eee\AFG\AFG_Build_Qwer.log buildProcess qqqq-eee-cntl   system_uu_gggg_p@ad    gx,wx    s(qqqq-rtl-etl-40-datamart-load-cms) & s(qqqq-eee-ess)  >E\:\gggg\logs\qqqq-eee-ess-saturday-cms-build.out      >E\:\gggg\logs\qqqq-eee-ess-saturday-cms-build.err      420     1       qqqq-M9887

如果您希望Excel更易于处理,将生成一个CSV文件,只需双击输出文件名即可打开Excel:

$ cat tst.awk
BEGIN { OFS="," }
{
    if ( numTags == 0 ) {
        tag = $1
        val = $2
        sub(/:$/,"",tag)
        tags[++numTags] = tag
        tag2val[tag] = val
        sub(/[^:]+: +[^ ]+ +/,"")
    }
    tag = val = $0
    sub(/: .*/,"",tag)
    sub(/[^:]+: /,"",val)
    tags[++numTags] = tag
    tag2val[tag] = val
}
tag == "application" {
    if ( !cnt++ ) {
        for (tagNr=1; tagNr<=numTags; tagNr++ ) {
            tag = tags[tagNr]
            printf "\"%s\"%s", tag, (tagNr<numTags ? OFS : ORS)
        }
    }
    for (tagNr=1; tagNr<=numTags; tagNr++ ) {
        tag = tags[tagNr]
        val = tag2val[tag]
        printf "\"%s\"%s", val, (tagNr<numTags ? OFS : ORS)
    }
    numTags = 0
}

$ awk -f tst.awk file
"insert_job","job_type","box_name","command","machine","owner","permission","condition","std_out_file","std_err_file","max_run_alarm","alarm_if_fail","application"
"aaa-bbb-ess-qqqqqqq-aaaaaa-aaaaaa","c","sss-eee-ess-saturday","$${qqqq-eee-eat-cmd} $${qqqq-eee-nas-cntrl-dir}\eee\CMS\CMS_C3.xml $${qqqq-eee-nas-log}\eee\AFG\AFG_Build_Qwer.log buildProcess","qqqq-eee-cntl","system_uu_gggg_p@ad","gx,wx","s(qqqq-rtl-etl-40-datamart-load-cms) & s(qqqq-eee-ess)",">E\:\gggg\logs\qqqq-eee-ess-saturday-cms-build.out",">E\:\gggg\logs\qqqq-eee-ess-saturday-cms-build.err","420","1","qqqq-M9887"

答案 1 :(得分:0)

如果这是一项一次性的工作,并且您不必担心源数据中的双引号,请尝试这样的操作。我假设您希望将逗号分隔的值放入电子表格中,并且数据位于名为foo.txt的文件中。

echo $(sed 's/^\([^:]*\): \(.*\)$/"\1",/g' foo.txt)
echo $(sed 's/^\([^:]*\): \(.*\)$/"\2",/g' foo.txt)