在bash脚本中重定向csv / excel文件中的进程输出

时间:2018-04-18 20:59:37

标签: bash awk sed grep

我在bash中编写了一个脚本,它生成磁盘I / O性能的输出,并以下列格式提供输出,我将其重定向到文本文件。

2018-04-18-12-09-32
File Size 250KB
dir /opt/testfile
WRITE TEST ==> 116 MB/s
READ TEST (W/O CACHE) ==> 350 MB/s
READ TEST (WITH CACHE) ==> 657 MB/s

但我希望它在.csv文件中生成此输出,并从文本文件中提取以下表格格式。

Date-time              Filename (being tested)     Filesize     Test type                      Speed
2018-04-18-12-09-32    /opt/testfile               1MB          READ TEST (W/O CACHE)           350 MB/s
2018-04-18-12-09-32    /opt/testfile               1GB          Write TEST (W/O CACHE)          500 MB/s

我尝试使用awk,sed,cut做了一些事情但是我无法生成结果。

建议将是一个很大的帮助。 在此先感谢你们:)

2 个答案:

答案 0 :(得分:1)

虽然在没有完整的输入文件和预期输出的情况下我还没有完全理解你的输入文件格式,但我试图做出最好的猜测。假设输入文件名是“textfile”,那么:

#!/bin/bash

declare -a datetimes
declare -A filesize
declare -A dir
declare -A testtype
declare -A speed

# extract parameters with regex from the input file
while read -r line; do
    if [[ "$line" =~ ^([0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+)$ ]]; then
        datetime="${BASH_REMATCH[1]}"
        datetimes+=($datetime)
    elif [[ "$line" =~ ^File\ Size\ +([[:alnum:]]+)$ ]]; then
        filesize[$datetime]="${BASH_REMATCH[1]}"
    elif [[ "$line" =~ ^dir\ +([^[:blank:]]+)$ ]]; then
        dir[$datetime]="${BASH_REMATCH[1]}"
    elif [[ "$line" =~ ^(.*TEST.*)\ +==\>\ +([0-9]+.+)$ ]]; then
        test="${BASH_REMATCH[1]}"
        testtype[$datetime]+="${test},"
        speed[$datetime,$test]="${BASH_REMATCH[2]}"
    fi
done < textfile

# report the results in csv format
printf "%s,%s,%s,%s,%s\n" "Date-time" "Filename (being tested)" "Filesize" "Test type" "Speed"
for d in ${datetimes[@]}; do
    test="${testtype[$d]}"
    ifs_b="$IFS"
    IFS=,
    for t in $test; do
        printf "%s,%s,%s,%s,%s\n" "$d" "${dir[$d]}" "${filesize[$d]}" "$t" "${speed[$d,$t]}"
    done
    IFS="$ifs_b"
done

从原始文件修改的文本文件示例:

2018-04-18-12-09-32
File Size 250KB
dir /opt/testfile
WRITE TEST ==> 116 MB/s
READ TEST (W/O CACHE) ==> 350 MB/s
READ TEST (WITH CACHE) ==> 657 MB/s
2018-04-19-01-23-45
File Size 1GB
dir /opt/testfile2
WRITE TEST ==> 120 MB/s
READ TEST (W/O CACHE) ==> 300 MB/s
READ TEST (WITH CACHE) ==> 600 MB/s

结果将是:

Date-time,Filename (being tested),Filesize,Test type,Speed
2018-04-18-12-09-32,/opt/testfile,250KB,WRITE TEST,116 MB/s
2018-04-18-12-09-32,/opt/testfile,250KB,READ TEST (W/O CACHE),350 MB/s
2018-04-18-12-09-32,/opt/testfile,250KB,READ TEST (WITH CACHE),657 MB/s
2018-04-19-01-23-45,/opt/testfile2,1GB,WRITE TEST,120 MB/s
2018-04-19-01-23-45,/opt/testfile2,1GB,READ TEST (W/O CACHE),300 MB/s
2018-04-19-01-23-45,/opt/testfile2,1GB,READ TEST (WITH CACHE),600 MB/s

希望这有帮助。

答案 1 :(得分:1)

带有awk的一个班轮

echo "Date-time              Filename (being tested)     Filesize     Test type                      Speed";cat 1.txt | tr '\n' '|' | nawk -F"|" '/WRITE TEST/ {split($2,a," ");printf("%-22s%-29s%-13s%-30s%-10s\n",$1,substr($3,index($3," ")),a[3],substr($4,0,index($4,"=")-1),substr($4,index($4,">")+1))} /READ TEST \(W\/O CACHE\)/ {printf("%-22s%-29s%-13s%-30s%-10s\n",$1,substr($3,index($3," ")),a[3],substr($5,0,index($5,"=")-1),substr($5,index($5,">")+1))} /READ TEST \(WITH CACHE\)/ {printf("%-22s%-29s%-13s%-30s%-10s\n", $1,substr($3,index($3," ")),a[3],substr($6,0,index($6,"=")-1),substr($6,index($6,">")+1))}'
Date-time              Filename (being tested)     Filesize     Test type                      Speed
2018-04-18-12-09-32    /opt/testfile               250KB        WRITE TEST                     116 MB/s
2018-04-18-12-09-32    /opt/testfile               250KB        READ TEST (W/O CACHE)          350 MB/s
2018-04-18-12-09-32    /opt/testfile               250KB        READ TEST (WITH CACHE)         657 MB/s