Excel の fill down 関数のように、テキスト ファイルの列を「下方向に埋める」コマンド

Excel の fill down 関数のように、テキスト ファイルの列を「下方向に埋める」コマンド

行と、その行内の列を含むテキスト ファイルがあります。基本的に、Excel の「下方向に埋める」機能を再現したいと考えています。つまり、行に空白の「セル」がある場合、その上の行を参照して、その上の対応するフィールドの値を下に埋めます。列区切りとして「^」が使用されている例:

London^Paris^Moscow^Berlin
^^Melbourne^New York^Washington
^^^Sydney^Singapore^New Delhi
^^New York^Washington
Kuala Lumpur^Bangkok^Hong Kong
^^^^Johannesburg^Sydney^Singapore^New Delhi
Amsterdam
^^Bucharest

... は次のようになります (わかりやすくするために項目は大文字で記入します)。

London^Paris^Moscow^Berlin
LONDON^PARIS^Melbourne^New York^Washington
LONDON^PARIS^MMELBOURNE^Sydney^Singapore^New Delhi
LONDON^PARIS^New York^Washington
Kuala Lumpur^Bangkok^Hong Kong
KUALA LUMPUR^BANGKOK^HONG KONG^^Johannesburg^Sydney^Singapore^New Delhi
Amsterdam
AMSTERDAM^^Bucharest

したがって、本質的には、関数は空白のフィールドを識別し、空白のフィールドがある場合は、その上の対応するフィールドから値をプルダウンします。フィールド/列の区切りを指定できることが重要です。何かアイデアはありますか?

答え1

awk -F'^' -v OFS='^' \
   '{
        for (i = 1; i <= NF; i++) {
                if ($i == "") $i = save[i]
                else          save[i] = $i
        }
        for (i = NF+1; i <= 99; i++) save[i] = ""
        print
    }'

save これは、 1 行から次の行に値を保存する (下方向に埋める) ために呼び出される配列を使用します。 内のすべての値awkは暗黙的に null に初期化されるため、saveデータが割り当てられるまで配列は空白になります。 (したがって、最初の行の空白フィールドは、そこにコピーする前のデータがないため、空白のままになります。)

各行ごとに、

  • この行()に存在する各フィールドについてfor (i = 1; i <= NF; i++)
    • 空白の場合は、この列に保存された(コピーされた)値を入力します。
    • それ以外の場合は、後続の行で使用できるように現在の値を保存します。
  • 次に、現在の行に存在しないすべての列の配列を消去しますsave。たとえば、行 4 (フィールドが 4 つだけ) に到達すると、行 3 の列 5 と 6 に「シンガポール」と「ニューデリー」が含まれていたことを「忘れて」しまいます。また、行 7 (フィールドが 1 つだけ) に到達すると、行 5 の列 2 に「バンコク」が含まれていたことを「忘れて」しまうため、行 8 (列 2 が空白) に入力できなくなります。

    99 を、1 行に表示されると予想されるフィールドの最大数に置き換えます。

関連情報