時々、追加の改行を含む入力ファイルを読む方法は?

時々、追加の改行を含む入力ファイルを読む方法は?

ほとんどの場合、次のような入力ファイルを取得します。

java-1.8.0-openjdk.x86_64  1:1.8.0.232.b09-1.el6_10        asyum:ol6_latest
java-1.8.0-openjdk-headless.x86_64 1:1.8.0.232.b09-1.el6_10        asyum:ol6_latest
kernel.x86_64              2.6.32-754.23.1.el6             asyum:ol6_latest

...whileループがあり、次のコードを使用して各行に対してfield1とfield2を正常にキャプチャできます。

f1=$(echo $line | awk '{print $1}')
f2=$(echo $line | awk '{print $2}')

ただし、時々、次のような入力ファイルが表示されます。

java-1.8.0-openjdk.x86_64  1:1.8.0.232.b09-1.el6_10        asyum:ol6_latest
java-1.8.0-openjdk-headless.x86_64
                           1:1.8.0.232.b09-1.el6_10        asyum:ol6_latest
kernel.x86_64              2.6.32-754.23.1.el6             asyum:ol6_latest

(ライン2を区切る追加の改行があることに注意してください。)

このタイプの入力をプログラムで処理するためのヒント/コツがあります(入力ファイルを手動でクリーンアップする代わりに)。

答え1

以下は、先行スペースにのみ依存するソリューションです。予想されるフィールド数に依存しません。

これGNUマニュアルsed「空白で始まる行を連結する」方法を提供します。

sed -E ':a ; $!N ; s/\n\s+/ / ; ta ; P ; D'

マニュアルでは、移植可能な(GNUではない)バリアントは次のように主張しています。

sed -e :a -e '$!N;s/\n  */ /;ta' -e 'P;D'

答え2

これにより、目的の効果を得ることができます。

#!/usr/bin/env bash

while read line; do
    declare -a array=($line)
    if  test ${#array[@]} != 3; then
        read line2
        array+=($line2)
    fi
    f1=${array[0]}
    f2=${array[1]}
    echo $f1 $f2
done

run with : test.sh < inputfile

行に3つの項目が含まれていることを確認し、そうでない場合は次の行を結合します。

答え3

とにかくそれを使っているので、awk完全に依存するのはどうですか?努力する

read f1 f2 <<< $(awk '{while (NF < 3) {getline X; $0 = $0 FS X};  print $1, $2}' file)

答え4

入力データの正しい形式の各行が3つの単語(ここでは空白文字を含まない文字列で緩く定義されている)で構成されていると仮定すると、入力データを前処理できます。

<input_file tr -s '[:blank:]' '\n' | paste - - - | column -t

<newline>ここでは、すべての空白文字(文字を含む)を単一に置き換え<newline>、結果を3単語行に再配置し、出力形式をきれいに指定します。最後のステップは、あなたの質問を考慮する際に不要な装飾的なステップです。

関連情報