複数行のデータを1行に結び付けるUnixスクリプト

複数行のデータを1行に結び付けるUnixスクリプト

1行のデータが新しい行区切り文字を使用して複数行に分割される大きなtsvファイルがあります。

タブの数に応じてそれらを組み合わせる必要があります。

例: 単一行のタブの総数が 995 であると仮定すると、データは次のように分割されます。

Row Number  Tab Count
Row 1       660
Row 2       0
Row 3       300         
Row 5       20
Row 6       15
Total       995

注:上記の線分は一貫性がなく、さまざまです。

タブ数を追加して合計が995に達したら、複数行のデータを1行にリンクする必要があります。

新しい行区切り文字に基づいて行を連結するには、次のコマンドがあります。

paste -sd '\n' inputfile > output file

知りたい、

  1. 他の行のタブ数を取得できる場合
  2. タブ数を追加して合計995個を獲得します。
  3. 合計に達すると、この行で追加されたタブの数を1行にリンクする必要があります。

シェルスクリプトを使用して、これが達成できるかどうかを教えてください。

ありがとうございます。 !

答え1

この種の問題と同様に、プロセスに後処理ステップを追加するのではなく、データを生成したプロセスを最初に修正することをお勧めします。そう言えばここにあなたができることがあります。

$ cat file
1       2
3
1       2       3
1
2
3
$ awk -v w=3 -f script.awk file
1       2       3
1       2       3
1       2       3

スクリプトawkは、プリセットされた数のフィールドが収集されるまで、入力からタブ区切りのフィールドを収集します。その後、収集されたフィールドを独自の行として出力し、入力から読み続けます。

出力のフィールド数は、上記wのようにコマンドラインに渡される値として提供されます。数量ですので参考にしてくださいフィールド、タップ数ではありません。

BEGIN { OFS = FS = "\t" }

function output_line () {
    # a function that outputs the nf elements in the array a
    # separated by OFS (tab) and terminated by ORS (newline)

    for (j = 1; j < nf; ++j)
        printf("%s%s", a[j], OFS)

    printf("%s%s", a[nf], ORS)
}

{
    # a:  an array of fields that we want to output together
    # nf: the length of that array

    # just add each field to the a array
    for (i = 1; i <= NF; ++i) {
        a[++nf] = $i

        # if enough has been read, output the collected data
        if (nf == w) {
            output_line()
            nf = 0
        }
    }
}

END {
    # output any data remaining in a
    if (nf > 0)
        output_line()
}

これは以下に関連しています。

tr '\t' '\n' <file | paste - - -

私の小さな例を見てみましょう。あなたの場合は、awk上記のスクリプトを使用するか、-v w=996996のダッシュでtr+コマンドを入力できますpaste

答え2

フィールド数に達するまで行を読み続けるのは役立ちますか?他の記事から:

awk -F'\t' '
        {while (NF<996) {getline X
                         $0 = $0 FS X
                        }
        }
1
' file

関連情報