N本の連続行をシェルにグループ化しますか?

N本の連続行をシェルにグループ化しますか?

この形式のテキストファイルがあるとしましょう。

field1a
field2a
field3a
field1b
field2b
field3b

3本(または一般にN本)の連続ラインを組み合わせたいです。sedbashシェルで他のコマンドラインユーティリティを使用してこれを行うにはどうすればよいですか?

期待される出力

field1a:field2a:field3a
field1b:field2b:field3b

答え1

 paste -sd '::\n' file

行がelf -dの場合、それ自体はで区切り、file改行文字はその順序で表示されます。spaste::d

 <file paste -d : - - -

pastestdin、stdin、およびstdin行を区切り文字で:開き、dstdinはfile

または:

 awk '{ORS=NR%3?":":"\n";print}' < file

出力レコード区切り文字は、改行文字かレコード(行)番号が3の倍数であるかOによって異なります。RS:RN

(入力のレコード数が3の倍数ではない場合、これらの方法は動作が異なります。)

答え2

出力形式の場合は、次のものを使用できます。printf

IFS='
'       # split on sequences of newline characters
set -f # disable globbing
printf "%s:%s:%s\n" $(cat file)

(空白行はスキップされます。)

またはsed(必要に応じて)

sed '$!N;$!N;s/\n/:/g' file

答え3

そしてsed

sed '$!N;$!N;y/\n/:/'

私の考えでは、これはより良いようですが、Nラインそれ以上でなければなりません。次のように行数が常にフィールドの末尾にあるようにするには、次のようにします。

sed '$q;N;/1.$/!s/\(..*\)\(\n\)/\2\1:/;//P;D
' <<\INPUT 
field1a
field1b
field2b
field1c
INPUT

出力

field1a
field1b:field2b
field1c

... thenで終わる1別の行に会うまで、thenの単一文字で終わる行を積み重ねます。1

発生フィールドの数に関係なく動作しますが、次のことも必要です。

sed '.../[^0-9]1.$/!...'

...複数の桁を入力する場合。

答え4

数百行以下の場合、またはグループごとのフィールド数が異なる場合は、viが適しています。

viで現在と次の2行(合計3行のテキスト)を結合するには...

    3J

このときカーソルが接続線にあるので次に進みます...

    j

ドットを使用して現在の行を同じに変更します。

    .

そしてまた…

    j
    .

こんな!最後のグループには3つではなく4つの行があります。最近の編集をキャンセルします...

    u

だから今回またやるのに…

    4J

次へ! ...

    j

… …など。

3億6,000万フィールドのデータベースロードに対してこれを行う予定であるか、連続フィールドが通常3つ、いくつかのグループが4つ、いくつかのグループが5〜6つの場合は、次のことを行う必要があります。難解な構文に耐え、ループから外れ、段階的にデータを調整し、それをテストしてエラーを警告するプログラムを書くこともできます。

しかし、小さな使い捨て作業であれば、数分間退屈に耐え、viを使用するだけです。

関連情報