結果

結果

一部のデータをジョブに変換する必要があります。私はこれがawkの非常に簡単な作業のように見えると確信していますが、私はそれが非常に不便です。

各データ要素(および列)はタブで区切られています。データ要素にはスペースと特殊文字を含めることができますが、タブを含めることはできません。

入力例:

column1 column2 column3
rowA1   rowA2   rowA3
rowB1   rowB2   rowB3

予想出力:

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

(何行でも数百行を超えない)

これを行う方法についての手がかりはありますか? (Linuxではawkまたは標準のコマンドラインツールを使用してください)

答え1

たとえば、

{
    if (NR==1){
        for (i=1; i<=NF; ++i){
            arr[i] = $i
        }
    }else{
        for (i=1; i<=NF; ++i){
            print(arr[i]," = ",$i)
        }
    }
    print("")
}

ランニング:

awk -f script.awk input

答え2

cat data |
while IFS=$'\t' read -r -a a; do
   case ${flag+'set'} in
      "set" )
         set -- "${a[@]}"
         for c in "${C[@]}"; do echo "$c = $1"; shift; done
         echo ;;

      * ) C=( "${a[@]}" ); flag= ;;
   esac
done

sed -Ee '
   1h;1N
   /^\n$/{
      $d;P;g;N
   }
   s/^(\S+)\s*((\S.*)?)\n(\S+)\s*((\S.*)?)/\1 = \4\n\2\n\5/
   P;D
' data

perl -F'\t+' -lane '
   @C or @C = @F,next;
   print "$C[$_] = $F[$_]" for 0 .. $#C;
   eof or print q[];
' data

結果

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

説明する

  1. bash

    C*) フラグがセットされていない間、配列の最初の行を保存します。その後、ここに来ないようにすばやく設定してください。 *)コマンドを使用してa配列をパラメータに分割しますset。 *) 次に、ループで「${c[@]}」を介してアクセスし、for$1に印刷(次に移動)する列を繰り返します。 *)IFSは設定に従ってタブに設定されます$'\t'。特殊文字の1つなので、一連の文字が1つに縮小されるため、空のフィールドは表示されません。

  2. perl

    *)FSを1つ以上のTAB:に設定し、-F'\t+'自動分割モードをオンにします。 *)配列bashの最初の行に列データを格納するソリューションベースのロジックと同じです。@C配列@Cと現在のレコードフィールドデータを@Fそれぞれ1つずつ印刷します。

  3. sed

    *) ここでは、まずすべてのタブ文字を空白に変換します。 *)最初の行と列のデータを予約済みスペースに保存します。 *) 他のすべての行の場合、列を現在の行に追加します。 *)その後、現在の行/列から最初の要素を選択し、これらの印刷内容を削除してパターンスペースを減らします。 *) 残りのスペースがないと停止状態が発生します。

関連情報