1つのデータ列(つまり、1行につき1つのデータ値)を含むファイルがあります。私はこのデータをいくつか解釈します。データセット;
データセットはNA
1 つ以上の行に分けられます。データセットの長さはさまざまです。これを複数列形式に変換したいと思います。ここで、各データセットは、入力ファイルに表示されるのと同じ順序で列にあります。
たとえば、次のファイルがあります(実際には、このファイルにはより多くのデータが含まれています)。
NA
4
3
5
7
8
3
NA
NA
NA
3
4
5
2
NA
2
7
4
6
9
NA
私の予想結果は次のとおりです。
4 3 2
3 4 7
5 5 4
7 2 6
8 . 9
3
8と9の間の点は実際には必要ありませんが、スペースで置き換えることができます。
答え1
awk
各データセット(データがNA
行の間にある)を別々のファイルに分割し、行をスキップしてNA
一緒に入れるpaste
ことができます。
awk '/^NA$/ && !NA{N++; NA=1; next} !/^NA$/{print >"file"N; NA=0}
END{system("paste file*")}' inile.txt
このNA
フラグは、ファイルを順次生成するために使用され、以下で使用できます。
awk '/^NA$/{N++; next} !/^NA$/{print >"file"N}
END{system("paste file*")}' inile.txt
出力は次のとおりです
4 3 2
3 4 7
5 5 4
7 2 6
8 9
3
答え2
この出力形式は私には適していません。私はこれがまったく実用的ではないと思います。
とにかく、1行に書き込んで次のように置き換えます(またはより良い方法は1行に保つことです)。
tr '\n' ' ' < example | tr 'N' '\n' | sed 's/^A //; /^$/d'
与えられた
4 3 5 7 8 3
3 4 5 2
2 7 4 6 9
答え3
シェルから変換するのは痛いです。以下はPerlの短い答えです。配列::転置::非定型CPANから
perl -MArray::Transpose::Ragged=transpose_ragged -lnE '
if (/NA/) { $n++; next } # next row
push @{$data[$n]}, $_; # creating the 2D matrix of data
} END {
say join "\t", @$_ for transpose_ragged [grep {defined} @data];
' file
別のアプローチは次のとおりです。以前のパイプラインはgawk
基本的に@n.caillouの答えと同じで、awkコードが変更されました。
paste -sd " " file | sed 's/NA/\n/g' | sed '/^ *$/d' | gawk '
{
for (i=1; i<=NF; i++) data[FNR][i] = $i
if (NF > max) max = NF
}
END {
for (i=1; i<=max; i++) {
for (j=1; j<=NR; j++) printf "%s\t", data[j][i]
print ""
}
}
'
GNU awkを使用した多次元配列の処理
答え4
これGNUデータの混合バージョン 1.1.1 が必要です。バージョン 1.0.7 では正しく動作しません。
#!/bin/bash
tr '\n' ' ' < input.txt |
sed 's/\s*NA\s*/\n/g;' |
sed '/^$/d' |
datamash --no-strict --filler="." -W -t' ' transpose
説明する
tr '\n' ' ' < input.txt
- すべての改行を空白に置き換えます。つまり、すべての行を1つの行にリンクします。sed 's/\s*NA\s*/\n/g;'
- すべての「NA」に隣接するスペースを改行文字に置き換えます。つまり、大きな行を複数の行に分割し、各行は水平に書かれた将来の列です。sed '/^$/d'
- 空白行をすべて削除します。datamash --no-strict --filler="." -W -t' ' transpose
--no-strict
- フィールド数が異なる行を許可する--filler="."
- 欠けている値をポイントで埋めます。スペースに変更されることがあります。-W
- スペース(1つ以上のスペースおよび/またはタブ)を入力フィールド区切り文字として使用します。-t' '
- 出力フィールド区切り記号としてタブの代わりにスペースを使用します。transpose
- 行を列に変換します。
入力する
NA
4
3
5
7
8
3
NA
NA
NA
3
4
5
2
NA
2
7
4
6
9
NA
出力
4 3 2
3 4 7
5 5 4
7 2 6
8 . 9
3 . .