一部のデータをジョブに変換する必要があります。私はこれが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
説明する
bash
C
*) フラグがセットされていない間、配列の最初の行を保存します。その後、ここに来ないようにすばやく設定してください。 *)コマンドを使用してa
配列をパラメータに分割しますset
。 *) 次に、ループで「${c[@]}」を介してアクセスし、for
$1に印刷(次に移動)する列を繰り返します。 *)IFSは設定に従ってタブに設定されます$'\t'
。特殊文字の1つなので、一連の文字が1つに縮小されるため、空のフィールドは表示されません。perl
*)FSを1つ以上のTAB:に設定し、
-F'\t+'
自動分割モードをオンにします。 *)配列bash
の最初の行に列データを格納するソリューションベースのロジックと同じです。@C
配列@C
と現在のレコードフィールドデータを@F
それぞれ1つずつ印刷します。sed
*) ここでは、まずすべてのタブ文字を空白に変換します。 *)最初の行と列のデータを予約済みスペースに保存します。 *) 他のすべての行の場合、列を現在の行に追加します。 *)その後、現在の行/列から最初の要素を選択し、これらの印刷内容を削除してパターンスペースを減らします。 *) 残りのスペースがないと停止状態が発生します。