每个sed匹配上的While循环

每个sed匹配上的While循环,sed,while-loop,Sed,While Loop,我正试图通过存储在本地工作站上的电子邮件文件进行解析。每个文件都包含硬件订单列表。某些文件在一个块中可能包含多个硬件列表,以Processor:开头,以ExtraIp:结尾。如果电子邮件只包含一个块,我当前的脚本就可以正常工作。当电子邮件文件包含如上所述的多个数据块时,就会出现问题 问题电子邮件示例: Processor: Intel Xeon E3-1270 V2 3.5GHZ, Quad Core RAM: 16GB DDR3 SDRAM HD1: 2 x SATA Hardware RAI

我正试图通过存储在本地工作站上的电子邮件文件进行解析。每个文件都包含硬件订单列表。某些文件在一个块中可能包含多个硬件列表,以Processor:开头,以ExtraIp:结尾。如果电子邮件只包含一个块,我当前的脚本就可以正常工作。当电子邮件文件包含如上所述的多个数据块时,就会出现问题

问题电子邮件示例:

Processor: Intel Xeon E3-1270 V2 3.5GHZ, Quad Core
RAM: 16GB DDR3 SDRAM
HD1: 2 x SATA Hardware RAID 1 (7,200 rpm)
(+1TB 7200 RPM SATA hard drive)
SSD: No SSD Drive
HD2: SATA Backup Drive
(+1 TB SATA (7,200 rpm))
HD3: No Additional Storage Array
ExtraIp: Public IP Addresses

Processor: Intel Xeon E3-1220 V2 3.1GHZ, Quad Core
RAM: 8GB DDR3 SDRAM
HD1: 2 x SATA Hardware RAID 1 (7,200 rpm)
(+1TB 7200 RPM SATA hard drive)
SSD: No SSD Drive
HD2: No Backup Drive
HD3: No Additional Storage Array
ExtraIp: Public IP Addresses
我的剧本:

#!/bin/bash
find ./email -print0 | while read -d $'\0' file
do
#### Sed and while loop here, with modification to the below lines to read data from the while loop instead of directly from each file ####
#### Example sed command: sed -n "/Processor:/,/ExtraIp:/p" $file ####

    order_date=$(echo $file | awk '{print $11}')
    grep "Processor:" "$file" | cut -d : -f2 | cut -d , -f1 | while read cpu_type
    do
            if [ "$cpu_type" != "" ]; then
                    echo $order_date
                    echo $cpu_type
                    ram_size=$(grep "RAM:" "$file" | cut -d : -f2)
                    if [ "$ram_size" != "" ]; then
                            echo $ram_size
                    fi
                    hd1_type=$(grep "HD1:" "$file" | cut -d : -f2)
                    if [ "$hd1_type" != "" ]; then
                            echo $hd1_type
                    fi
                    hd1_size=$(grep -A1 "HD1:" "$file" | tail -n1)
                    if [ "$hd1_size" != "" ]; then
                            echo $hd1_size
                    fi
                    ssd_type=$(grep "SSD:" "$file" | cut -d : -f2)
                    ssd_type1=$(grep "SSD:" "$file" | cut -d : -f2 | awk '{print $1}')
                    if [ "$ssd_type" != "" ]; then
                            echo $ssd_type
                    fi
                    if [[ "$ssd_type1" != "No"  &&  "$ssd_type1" != "" ]]; then
                            ssd_size=$(grep -A1 "SSD:" "$file" | tail -n1)
                            echo $ssd_size
                    else
                            ssd_size="No SSD"
                            echo $ssd_size
                    fi
                    hd2_type=$(grep "HD2:" "$file" | cut -d : -f2)
                    hd2_type1=$(grep "HD2:" "$file" | cut -d : -f2 | awk '{print $1}')
                    if [ "$hd2_type" != "" ]; then
                            echo $hd2_type
                    fi
                    if [[ "$hd2_type1" != "No"  &&  "$hd2_type1" != "" ]]; then
                            hd2_size=$(grep -A1 "HD2:" "$file" | tail -n1)
                            echo $hd2_size
                    else
                            hd2_size="No HD2"
                            echo $hd2_size
                    fi
                    hd3_type=$(grep "HD3:" "$file" | cut -d : -f2)
                    hd3_type1=$(grep "HD3:" "$file" | cut -d : -f2 | awk '{print $1}')
                    if [ "$hd3_type" != "" ]; then
                            echo $hd3_type
                    fi
                    if [[ "$hd3_type1" != "No"  &&  "$hd3_type1" != "" ]]; then
                            hd3_size=$(grep -A1 "HD3:" "$file" | tail -n1)
                            echo $hd3_size
                    else
                            hd3_size="No HD3"
                            echo $hd3_size
                    fi
            echo "$order_date,$cpu_type,$ram_size,$hd1_type,$hd1_size,$hd2_type,$hd2_size,$hd3_type,$hd3_size" >> order_list.csv
            fi
    done
done
预期产出:

如果电子邮件仅包含一段文字,我将获得正确的输出:

2014-04-01,Intel Xeon E3-1270 V2 3.5GHZ, 16GB DDR3 SDRAM, 2 x SATA Hardware RAID 1 (7,200 rpm),(+1TB 7200 RPM SATA hard drive), SATA Backup Drive,(+1 TB SATA (7,200 rpm)), No Additional Storage Array,No HD3
如果电子邮件包含多个文本块,我将获得以下输出:

2014-04-01,Intel Xeon E3-1270 V2 3.5GHZ, 16GB DDR3 SDRAM
8GB DDR3 SDRAM, 2 x SATA Hardware RAID 1 (7,200 rpm)
2 x SATA Hardware RAID 1 (7,200 rpm),    (+1TB 7200 RPM SATA hard drive), SATA Backup Drive
No Backup Drive,    HD3: No Additional Storage Array, No Additional Storage Array
No Additional Storage Array,    ExtraIp: Public IP Addresses
2014-04-01,Intel Xeon E3-1220 V2 3.1GHZ, 16GB DDR3 SDRAM
8GB DDR3 SDRAM, 2 x SATA Hardware RAID 1 (7,200 rpm)
2 x SATA Hardware RAID 1 (7,200 rpm),    (+1TB 7200 RPM SATA hard drive), SATA Backup Drive
No Backup Drive,    HD3: No Additional Storage Array, No Additional Storage Array
No Additional Storage Array,    ExtraIp: Public IP Addresses
在第二次输出中,来自两个文本块的数据对每个CSV值内存和驱动器进行复制。我的计划是在脚本中的上述注释空间中包含sed命令的另一个while循环,然后修改每个命令以从while循环读取数据

要使用的sed命令示例:

sed -n "/Processor:/,/ExtraIp:/p" $file
您的解析脚本使用grep提取一个字段,当$file包含两个相同的字段时,grep将同时提取这两个字段

在Awk中进行所有解析时,最好进行重构。我不会为你完成它,但这应该是一个好的开始

awk 'BEGIN { split("Processor:RAM:HD1:SSD:HD2:HD3", f, /:/) }
    /^Processor:/ { delete a }  # forget any prevous record
    /^(Processor|RAM|HD[123]|SSD):/ { i=$1; sub(/:/,"",i); 
        $1=""; sub(/^ /,""); a[i]=$0 }
    i ~ /^(HD[123]|SSD)$/ && $1 == "No" { a[i] = "No " i; i=""; next }
    i ~ /^(HD[123]|SSD)$/ && !k { k=i; next }  # remember key for two-line entry
    k { a[k] = a[k] "," $0; k=i="" }
    /^ExtraIp: / {s=""; for (i=1; i<=length(f); i++) {
        printf("%s%s", s, a[f[i]]); s="," } printf "\n" }' "$file"

如果您在运行sed之前向我们展示数据,然后在期末考试中展示您想要的内容,那会更好。也许一个awk可以一次性完成所有工作,而不需要一段时间。一组小样本输入涵盖了所有相关案例,该样本的必需输出、您的代码、错误MSG、您的输出都是一个很好的问题。祝你好运。这帮助我解决了使用grep计算处理器出现次数的问题,使用awk通过循环运行该计数,根据grep计数选择每个块并解析出所需数据。我拼凑的脚本解析任意数量的记录并打印每个记录。应该不需要单独的grep,如果需要的话,应该将它考虑到Awk脚本中,如果我还没有这样做的话。您可能需要对其进行调整,以便正确地忽略电子邮件标题等,但在while read file循环中,您或多或少都需要这样做。