空行を上記の内容に置き換える

空行を上記の内容に置き換える

Linuxコンピュータでタブ区切りのテキストファイルの空白行を上の行の内容に置き換える方法は?たとえば、

101 abc group1
765 efg group2
345 hij group4

456 gfd group9
762 ert group7


554 fgt group11

予想出力:

101 abc group1
765 efg group2
345 hij group3
345 hij group3
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11

答え1

これは1つの方法ですawkpゼロの場合は前の行を保持)。NF

awk 'NF {p = $0} {print p}' file

p行が空でない場合は、後で使用するために行を保存して印刷しますp

(空行の場合NF==0)私たちはp

答え2

In awk(これにより、空でない最初の行の前にすべての空白行が印刷されます):

$ awk '{ if(! NF){$0=last}else{last=$0;}}1' file
101 abc group1
765 efg group2 
345 hij group4 
345 hij group4 
456 gfd group9 
762 ert group7 
762 ert group7 
762 ert group7 
554 fgt group11  

説明する:

NF保存されたフィールドの数。行が空の場合はフィールドがないため、変数はになります0

  • if(! NF){$0=last}:フィールド数が0(空行)の場合、現在の行($0)は変数の値に設定されますlast
  • else{last=$0;}:フィールドがある場合、この行は空ではなく、lastこの行の内容を保存するように設定されます。
  • 1:終わりにある唯一のものはawkトリックです。何かがtrueと評価されると(0はfalseなので、1または0より大きい他の整数は常にtrueです)、awkは現在の行を印刷します。1したがって、これはprint $0
$ awk '! NF ? $0=last : last=$0;' file
101 abc group1
765 efg group2 
345 hij group4 
345 hij group4 
456 gfd group9 
762 ert group7 
762 ert group7 
762 ert group7 
554 fgt group11  

説明する これは上記の概念ですが、より簡潔に書かれています。私たちは使用しています三項演算子。両方の条件のいずれかが常に真であるため(真であるかどうかにかかわらNFず、三項演算子は常に真を返します)、両方の条件は印刷される行になります(行が空で空白行または行に表示されない項目がない限り)。 )でのみ構成されています0。ただし、NF設定されていない場合は設定し、設定$0lastれている場合は設定lastします$0。結果は私たちが望む結果です。

上記は行だけを印刷しないので、問題のある行の0代わりにこれを使用できます。

awk '{! NF ? $0=last : last=$0};1' file

答え3

提供された入力を使用して、次の操作を行いますsed

$ sed -n '/^$/{g;};h;p' infile
101 abc group1
765 efg group2
345 hij group4
345 hij group4
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11 
$

注:'/^$/{g;};h;p'明らかに、それは'/^$/g;h;p'Just my styleでより一般的に/正確に書かれています。

guest_7指摘したように(ありがとう)、コマンドsedは次のように簡単に書くこともできます。sed '/^$/g;h' infile

指摘したようにterdon、私が最初に考えなかったのは、「空」の行にスペースやタブ(スペース)を含めることができるということです。この場合、より安定したソリューションは次のとおりです。

$ sed '/^\s*$/g;h' infile

さまざまなロケールをサポートするより移植性の高いソリューションは次のとおりです。

$ sed '/^[[:blank:]]*$/g;h' infile

答え4

既存の回答に追加:

awk 'NR<2 && !NF{next} NF{print} !NF{print line} NF{line=$0}' test

...空の最初の行も処理します(以前の入力がないため無視します)。

関連情報