Awkを使用したファイルの列のマージ

Awkを使用したファイルの列のマージ

入力する:

ABC,SSSD,12345,NSS,12345,xxx,TS11
,,,,,,TS21
,,,,,,TS22
,,,,,,BS26
,,,,,,GPRS
ABC,SSSD,12356,NSS,12356,xxx,TS11
,,,,,,TS21
,,,,,,TS22
,,,,,,GPRS
,,,,,,BS26

出力:

ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS
ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26

以下のスクリプトを書いてみました。しかし、これはパフォーマンス集約的です。

#!/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"

誰もがawkを使用してこれを行うより良い方法またはより良い方法を提案できますか?

答え1

空白があまりにもトリッキーでない場合は、次の2つのawkルールを使用して実行できます。

 awk '$1 { printf "\n" $0 } !$1 { printf OFS $7 }' FS=, OFS='|' infile

これにより、出力の先頭に空白行が残り、最後にも空白行が残ります。この問題を解決するには、ifANDEND句を追加してください。

awk '$1 { if(NR>1) printf "\n"; printf $0 } !$1 { printf OFS $7 } END { printf "\n" }' FS=, OFS='|' infile

出力:

ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS
ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26

編集 - $ 0の%を参照してください。

Glennがコメントで指摘したように、行にが含まれている場合は、フォーマット文字列を使用して呼び出す方が%安全です。たとえば、次のようになります。printf

awk '$1 { if(NR>1) printf "\n"; printf "%s", $0 } !$1 { printf OFS"%s", $7 } END { printf "\n" }' FS=, OFS='|' infile

答え2

マージする行数が一定の場合は、awk行番号を確認して行の種類を確認できます。

$ awk -F, '1==NR%5 { printf $0 "|";next } { printf $7 (NR%5?"|":"\n") }' DATA
ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS
ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26

答え3

その他sed:

sed ':;N;s/\n,,,*/|/;t;P;D' file

答え4

常に同じ数の行(5)がある場合との組み合わせは、pastesedのことができます。

paste -d',' - - - - - <file | sed 's/,\{2,\}/|/g'

1)paste5行を,区切り記号にマージします。 2)複数の(2つ以上の)コンマを縦棒で置き換えます。

関連情報