列を1つに結合(スタック)

列を1つに結合(スタック)

各列が列内で互いに「重なるように」フォーマットを再指定するデータ列が複数あります。

入力例:

1  2  3  4
1  2  3  4

希望の出力:(「1」と「3」が欠落している古いスペルエラーを修正しました。)

1
1
2
2
3
3
4
4

(時々列の間にスペースを追加したい場合もあります)

編集する: 「間の空間」の説明は不明です。たまには、積み重ねられた列の間に空の行が欲しい時があります。以下のEd Mortonの回答を適用すると、次のように達成できます。

awk '
{for (i=1; i<=NF; i++) a[i]=a[i] $i ORS}
END {for (i=1; i<=NF; i++) printf "%s", a[i](i==NF?"":"\n")}
' file

答え1

datamashデータを置き換えてからスペースを改行文字に変換するために使用されますtr-s複数のスペースを1つに圧縮している間)。

datamash -t' ' transpose <infile | tr -s ' ' '\n'

答え2

これはおそらく、すべてのUnixシステムのすべてのシェルでawkを使用して欲しいものです。

$ awk '
    { for (i=1; i<=NF; i++) a[i] = a[i] $i ORS }
    END { for (i=1; i<=NF; i++) printf "%s", a[i] }
' file
1
1
2
2
3
3
4
4

答え3

GNU grepはどうですか?

grep -o '\S*' infile

または拡張して次のようにします\S

grep -o '[^ \t\r\n\v\f]*' infile

列の順序を維持する必要がある場合は、試してみてください(GNUソートを使用)。

$ awk '{for (i=1;i<=NF;i++){ print i,$i }}' infile | 
      sort -snbk 1,1 | 
      awk '{$1=""}1'

1
1
2
2
3
3
4
4

または、awkおよび熱転置に似た手順を使用してください。

awk '{ for(i=1;i<=NF;i++) { f[i]=(f[i]==""?"":f[i] ORS) $i; if(NF>n) n=NF}}
       END { for(i=1; i<=n; i++) { print f[i] }  }
    '  infile

答え4

この回答は、列と行が印刷される順序を切り替えることによって、元のデータを本質的に転置することに依存します。

OPの質問で同じ出力が更新されましたが、これはもともと期待どおりに正しくありませんでした。

for i in `seq 4`; do 
    awk -v field=$i '{ print $field }' infile; 
done

1
1
2
2
3
3
4
4

関連情報