簡體   English   中英

如何使用 BASH 將 .txt 文件數據存儲在 CSV 文件的不同列中?

[英]How to store .txt file data in different columns of a CSV file using BASH?

我有一個具有以下數據結構的 .txt 文件:

Scan Times:
 33.3 seconds
 77.4 seconds
 33.3 seconds
 77.4 seconds

Check Times:
 110.30 seconds
 72.99 seconds
 72.16 seconds
 110.30 seconds

Move Times:
 73.66 seconds
 90.77 seconds
 72.87 seconds
 71.75 seconds
 
Switch Times:
 92.0 seconds
 78.6 seconds
 77.8 seconds
 84.9 seconds

我現在想要獲取該 .txt 文件並創建一個具有以下格式的 CSV 文件。

在此處輸入圖片說明

到目前為止,我的 bash 腳本有一個非常基本的布局,但我不確定如何繼續:

inputFiles=("./Successes/SuccessSummary.txt" "./Failures/FailSummary.txt")
touch results.csv

for file in "${inputFiles[@]}"
do 
    while IFS= read -r line
    do
        #echo $line
        if [ "$line" = "Scan Times:" ]
        then 
        fi

        if [ "$line" = "Check Times:" ]
        then 
        fi

        if [ "$line" = "Move Times:" ]
        then 
        fi
        
        if [ "$line" = "Switch Distances:" ]
        then 
        fi
    done < "$file"
done

這是一個執行此操作的awk腳本:

#!/usr/bin/awk -f

BEGIN {
    OFS=","
    colnum=0
}

/:$/ {
    data[++colnum,1]=$0
    rownum=1
}

/seconds$/ {
    data[colnum,++rownum]=$1
}

END {
    for (r = 1; r <= rownum; r++) {
        for (c = 1; c <= colnum; c++) {
            printf "%s%s", data[c,r], (c == colnum ? RS : OFS)
        }
    }
}

例子:

$ ./pivot input.txt
Scan Times:,Check Times:,Move Times:,Switch Times:
33.3,110.30,73.66,92.0
77.4,72.99,90.77,78.6
33.3,72.16,72.87,77.8
77.4,110.30,71.75,84.9

在每個 Unix 機器上的任何 shell 中使用任何 awk:

$ cat tst.awk
BEGIN { RS=""; FS="\n"; OFS="," }
{
    for (i=1; i<=NF; i++) {
        if (i > 1) {
            gsub(/[^0-9.]/,"",$i)
        }
        vals[i,NR] = $i
    }
}
END {
    for (i=1; i<=NF; i++) {
        for (j=1; j<=NR; j++) {
            printf "%s%s", vals[i,j], (j<NR ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file
Scan Times:,Check Times:,Move Times:,Switch Times:
33.3,110.30,73.66,92.0
77.4,72.99,90.77,78.6
33.3,72.16,72.87,77.8
77.4,110.30,71.75,84.9

如果ed在 unix/linux 實用程序的幫助下可用/可接受。

用一個文件。

腳本my_script

#!/bin/sh

ed -s "$1" <<-EOF
 g/.\\{1,\\}/s/^ //\\
 s/ seconds//
 w tmpa.$$
 %d
 r !pr -t4 -s, tmpa.$$
 d
 !rm tmpa.$$
 w result.csv
 %p
 Q
EOF

然后

./myscript ./Successes/SuccessSummary.txt

result.csv的輸出和內容

Scan Times:,Check Times:,Move Times:,Switch Times:
33.3,110.30,73.66,92.0
77.4,72.99,90.77,78.6
33.3,72.16,72.87,77.8
77.4,110.30,71.75,84.9

用兩個文件。 (只需將第一個文件的內容與第二個文件一起使用。)

#!/bin/sh

ed -s "$1" <<-EOF
 g/.\\{1,\\}/s/^ //\\
 s/ seconds//
 w tmpa.$$
 %d
 r !pr -t4 -s, tmpa.$$
 d
 w tmpa.$$
 E $2
 g/.\\{1,\\}/s/^ //\\
 s/ seconds//
 w tmpb.$$
 %d
 r !pr -t4 -s, tmpb.$$
 d
 w tmpb.$$
 %d
 r !pr -mts, tmpa.$$ tmpb.$$
 %p
 w result.csv
 !rm tmp[ab].$$
 Q
EOF

然后

./myscript ./Successes/SuccessSummary.txt ./Failures/FailSummary.txt

result.csv的輸出和內容

Scan Times:,Check Times:,Move Times:,Switch Times:,Scan Times:,Check Times:,Move Times:,Switch Times:
33.3,110.30,73.66,92.0,33.3,110.30,73.66,92.0
77.4,72.99,90.77,78.6,77.4,72.99,90.77,78.6
33.3,72.16,72.87,77.8,33.3,72.16,72.87,77.8
77.4,110.30,71.75,84.9,77.4,110.30,71.75,84.9

  • ed腳本有兩個臨時文件tmpa.$$tmpb.$$但它在!rm tmpa ...所在的行被刪除/刪除。

  • 輸出寫入文件result.csv

  • Ed是一個文件編輯器,而不是像awkbash這樣的腳本/編程語言,並不是每個人都喜歡ed ,但它仍然是一個選項/解決方案。

這可能對你有用(GNU sed、csplit & paste):

sed '/\S/!d;s/^ \| seconds//g' file |
csplit -zs - '/:/' '{*}' && paste -d, xx* && rm xx*

使用 sed 刪除空行和不需要的空格和文字。

使用 csplit 將文件拆分為單獨的部分,即 xx00 ...

使用 paste 將分隔部分合並成一個,使用逗號作為字段分隔符。

清理遺留的文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM