每个sed匹配上的While循环
我正试图通过存储在本地工作站上的电子邮件文件进行解析。每个文件都包含硬件订单列表。某些文件在一个块中可能包含多个硬件列表,以Processor:开头,以ExtraIp:结尾。如果电子邮件只包含一个块,我当前的脚本就可以正常工作。当电子邮件文件包含如上所述的多个数据块时,就会出现问题 问题电子邮件示例:每个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: 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循环中,您或多或少都需要这样做。