Vin*_*eth 5 awk text-processing
输入:
ABC,SSSD,12345,NSS,12345,xxx,TS11
,,,,,,TS21
,,,,,,TS22
,,,,,,BS26
,,,,,,GPRS
ABC,SSSD,12356,NSS,12356,xxx,TS11
,,,,,,TS21
,,,,,,TS22
,,,,,,GPRS
,,,,,,BS26
Run Code Online (Sandbox Code Playgroud)
输出:
ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS
ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26
Run Code Online (Sandbox Code Playgroud)
我已经尝试过编写以下脚本。但它是性能密集型的:
#!/bin/bash
head -2 $1 | tail -1 >> $1"_output"
sed '1,2d' $1 > temp$1.txt
cp temp$1.txt $1
rm -f temp$1.txt
while IFS='' read -r line || [[ -n $line ]]; do
# echo "main line -- "$line
# echo "prev line -- "$prevLine
service=`echo $line | cut -d "," -f1`
value=`echo $line | cut -d "," -f7`
if [ "$service" != "" ]
then
if [ "$prevLine" != "" -a "$mvalue" != "" ]
then
echo $prevLine$mvalue >> $1"_output"
fi
prevLine=$line
mvalue=""
else
#echo $value
mvalue=$mvalue"|"$value
#echo $mvalue
fi
done < "$1"
echo $prevLine$mvalue >> $1"_output"
Run Code Online (Sandbox Code Playgroud)
有人可以建议使用 awk 或任何更好的方法来执行此操作的更好方法吗?
如果你对空白不太挑剔,你可以使用两个 awk 规则,如下所示:
awk '$1 { printf "\n" $0 } !$1 { printf OFS $7 }' FS=, OFS='|' infile
Run Code Online (Sandbox Code Playgroud)
这会在输出的开头留下一个空行,并在结尾处漏掉一个。要修复此添加if和END子句:
awk '$1 { if(NR>1) printf "\n"; printf $0 } !$1 { printf OFS $7 } END { printf "\n" }' FS=, OFS='|' infile
Run Code Online (Sandbox Code Playgroud)
输出:
ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS
ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26
Run Code Online (Sandbox Code Playgroud)
正如格伦在评论中指出的那样,如果您的行包含%,则printf使用格式字符串进行调用会更安全,例如:
awk '$1 { if(NR>1) printf "\n"; printf "%s", $0 } !$1 { printf OFS"%s", $7 } END { printf "\n" }' FS=, OFS='|' infile
Run Code Online (Sandbox Code Playgroud)