bash マトリクス変換shell

#!/bin/bash
#(1)カンマ変換シェル
 #csvファイルを取得 
csvfile=$1
ymd=$(date '+%Y%m%d%H%M%S')
lineprime=1

cp ${csvfile} ${csvfile}_bk #ファイル全体の行数を取得 
fileline=$(grep -c "." ${csvfile}_bk)
 #整形ファイル 
outputfile=${ymd}_shaping.txt
 #縦の論理 
while read line; do

       #現在行を取得 
       currentline=$lineprime

       #現在行がファイルの全体行数よりも大きい場合はbreakで抜ける
       #if  [[ $currentline -gt $fileline ]]; then
       # break
       #fi 

       #前行を取得 
       #beforeline  =$(expr $currentline - 1)
       #前行のカンマ数  (最大数)を取得
       #beforelinekanma  =$(sed -n ''${beforeline}p'' ${csvfile}_bk | awk -F ',' '{print NF}')
       #現在行のカンマ数  (最大数)を取得
       currentlinekanma=$(sed -n ''${currentline}p'' ${csvfile}_bk | awk -F ',' '{print NF}')

       #########################
       # 前行カンマ整形処理 start
       tmpprime=0
       for prime in $(seq 1 $currentlinekanma); do
               #前行の配列を取得 
               currentarray_index=$(sed -n ''${currentline}p'' ${csvfile}_bk | awk -F [,] '{print $'$prime'}')
               if [[ $(echo $currentarray_index | grep "." | wc -l) -eq 1 ]]; then
                       tmpprime=$prime
               fi
       done

       #最末尾の値以降のnull部分以外のみをcsvファイルに残す 
       tmpprime2=$(sed -n ''${currentline}p'' ${csvfile}_bk | cut -d ',' -f -${tmpprime})
       sed -i ''${currentline}''d ${csvfile}_bk
       #最終行だけ挿入できない問題を解消するために分岐 
       if [[ $currentline -eq $fileline ]]; then
               sed -i '$a '${tmpprime2}'' ${csvfile}_bk
       else
               sed -i ''${currentline}'i '${tmpprime2}'' ${csvfile}_bk
       fi

       # カンマ整形処理 finish
       #########################

       lineprime=$((++lineprime))

done <${csvfile}_bk
 #初期化 
lineprime=1

while read line; do

       lineprime=$((++lineprime))
       #現在行を取得 
       currentline=$lineprime
       #現在行がファイルの全体行数よりも大きい場合はbreakで抜ける
       if [[ $currentline -gt $fileline ]]; then
               break
       fi
       #前行を取得 
       beforeline=$(expr $currentline - 1)
       #現在行のカンマ数  (最大数)を取得
       currentlinekanma=$(sed -n ''${currentline}p'' ${csvfile}_bk | awk -F ',' '{print NF}')
       #現在行のカンマ数  (最大数)の値取得
       currentlinekanmaprime=$(sed -n ''${currentline}p'' ${csvfile}_bk | awk -F [,] '{print $'$currentlinekanma'}')
       #前行のカンマ数  (最大数)を取得
       beforelinekanma=$(sed -n ''${beforeline}p'' ${csvfile}_bk | awk -F ',' '{print NF}')
       #前行のカンマ数  (最大数)の値取得
       beforelinekanmaprime=$(sed -n ''${beforeline}p'' ${csvfile}_bk | awk -F [,] '{print $'$beforelinekanma'}')

       #現在行のカンマ数  (最大数)の値取得が1の場合は、何もしない。
       if [[ $currentlinekanma == 1 ]]; then
               continue
       fi

       currentarray=()
       #カンマ数が1以下の場合は現在の値だけを出力  。カンマ数が1以上であれば実施する。
       if [[ $beforelinekanma -ge 1 ]]; then
               #前行の配列を取得 
               beforearray=$(sed -n ''${beforeline}p'' ${csvfile}_bk | awk -F [,] '{print $0}' | sed 's/,/"" /g')

               #コピーされた前行配列を  、現在行の(最大数-1)分だけコピーする。
               count=0
               for t in ${beforearray[@]}; do
                       currentarray+=($t)
                       count=$((++count))

                       #配列の末尾に現在行の現在行の最大数値を付与する 
                       if [[ ${count} -eq $(expr ${currentlinekanma} - 1) ]]; then
                               currentarray+=($currentlinekanmaprime)
                               break
                       fi
               done

       else
               currentarray+=($currentlinekanmaprime)
       fi
       #現在行を出力する
       printnum=$(echo ${currentarray[*]} | sed 's/""//g' | sed 's/ /,/g')
       sed -i ''${currentline}''d ${csvfile}_bk

       #現在行がファイルの全体行数よりも大きい場合はbreakで抜ける
       if [[ $currentline -eq $fileline ]]; then
               sed -i '$a '${printnum}'' ${csvfile}_bk
       else
               sed -i ''${currentline}'i '${printnum}'' ${csvfile}_bk
       fi
done <${csvfile}_bk
 #退避ファイルを元ファイルに戻す  #mv  ${csvfile}_bk ${outputfile}

cat ${csvfile}_bk
[root@localhost ~]# shfmt  a.sh > b.sh
[root@localhost ~]# mv b.sh substring_hierarchy_csv.sh
[root@localhost ~]# cat substring_hierarchy_csv.sh
#!/bin/bash
 #csvファイルを取得 
csvfile=$1
ymd=$(date '+%Y%m%d%H%M%S')
lineprime=1

cp ${csvfile} ${csvfile}_bk #ファイル全体の行数を取得 
fileline=$(grep -c "." ${csvfile}_bk)
 #整形ファイル 
outputfile=${ymd}_shaping.txt
 #縦の論理 
while read line; do

       #現在行を取得 
       currentline=$lineprime

       #現在行がファイルの全体行数よりも大きい場合はbreakで抜ける
       #if  [[ $currentline -gt $fileline ]]; then
       # break
       #fi 

       #前行を取得 
       #beforeline  =$(expr $currentline - 1)
       #前行のカンマ数  (最大数)を取得
       #beforelinekanma  =$(sed -n ''${beforeline}p'' ${csvfile}_bk | awk -F ',' '{print NF}')
       #現在行のカンマ数  (最大数)を取得
       currentlinekanma=$(sed -n ''${currentline}p'' ${csvfile}_bk | awk -F ',' '{print NF}')

       #########################
       # 前行カンマ整形処理 start
       tmpprime=0
       for prime in $(seq 1 $currentlinekanma); do
               #前行の配列を取得 
               currentarray_index=$(sed -n ''${currentline}p'' ${csvfile}_bk | awk -F [,] '{print $'$prime'}')
               if [[ $(echo $currentarray_index | grep "." | wc -l) -eq 1 ]]; then
                       tmpprime=$prime
               fi
       done

       #最末尾の値以降のnull部分以外のみをcsvファイルに残す 
       tmpprime2=$(sed -n ''${currentline}p'' ${csvfile}_bk | cut -d ',' -f -${tmpprime})
       sed -i ''${currentline}''d ${csvfile}_bk
       #最終行だけ挿入できない問題を解消するために分岐 
       if [[ $currentline -eq $fileline ]]; then
               sed -i '$a '${tmpprime2}'' ${csvfile}_bk
       else
               sed -i ''${currentline}'i '${tmpprime2}'' ${csvfile}_bk
       fi

       # カンマ整形処理 finish
       #########################

       lineprime=$((++lineprime))

done <${csvfile}_bk
 #実行確認 
$ cat test.txt
1.java
,method_1_1
,method_1_2
2.java
,method_2_1
,method_2_2
3.java
,method_3_1
,method_3_2
4.java
,method_4_1
,method_4_2

$ bash substring_hierarchy_csv.sh test.txt csv
1.java
1.java,method_1_1
1.java,method_1_2
2.java
2.java,method_2_1
2.java,method_2_2
3.java
3.java,method_3_1
3.java,method_3_2
4.java
4.java,method_4_1
4.java,method_4_2
#!/bin/bash
#(2)カンマ戻し変換シェル
while read line
do
 #デリミタ数を数える
 delimiter_num=$(echo ${line}|awk -F ',' '{print NF}')
 #末尾のデータを取る 
 suffixdata=$(echo ${line}|awk '{print $NF}')

 #デリミタ数が1の場合は末尾だけを出す 
 if [[ ${delimiter_num} = 1 ]]; then
   echo ${suffixdata}
 #デリミタ数が2以上 (デリミタ数 - 1の数「,」 + 末尾データを出力する)
 else
   suffixdata=$(expr ${delimiter_num} - 1)
   cat <(seq 1 ${suffixdata}|sed -E "s/[0-9]+/,/g"|tr "\n" " "|sed -E "s/ | $//g") <(echo ${line}|awk -F [,] '{print $NF}')
 fi
done < ${1} 
 #確認 
$ cat hoge
1.java
1.java,method_1_1
1.java,method_1_2
2.java
2.java,method_2_1
2.java,method_2_2
3.java
3.java,method_3_1
3.java,method_3_2
4.java
4.java,method_4_1
4.java,method_4_2
 #実行をしてみる 
$ bash substring_hierarchy_modoshi_csv.sh hoge
1.java
,method_1_1
,method_1_2
2.java
,method_2_1
,method_2_2
3.java
,method_3_1
,method_3_2
4.java
,method_4_1
,method_4_2


この記事が気に入ったらサポートをしてみませんか?