特定の位置にタブ文字(区切り文字)を挿入するsedまたはawkコマンド

特定の位置にタブ文字(区切り文字)を挿入するsedまたはawkコマンド

同じ列のテーブルに変換するために、可変数の区切り文字を持つテーブルを解析しようとしています。

cluster=96\troot\tcellular organisms\tno_rank no_rank$

cluster=42\troot\tcellular organisms\tBacteria\tno_rank\tno_rank\tsuperkingdom$

cluster=362\troot\tcellular organisms\tBacteria\tProteobacteria\tno rank\tno rank\tsuperkingdom\tphylum$

cluster=12330\troot\tcellular organisms\tBacteria\tTerrabacteria\tFirmicutes\tClostridia\tClostridiales\tClostridiaceae\tClostridium\tno rank\tno rank\tsuperkingdom\tno rank\tphylum\tclass\torder\tfamily\tgenus$

予想される出力は次のとおりです。

cluster=96\troot\tcellular organisms\t\t\t\t\t\t\t\tno_rank\tno_rank\t\t\t\t\t\t\t$

cluster=42\troot\tcellular organisms\tBacteria\t\t\t\t\t\t\tno_rank\tno_rank\tsuperkingdom\t\t\t\t\t\t$

cluster=362\troot\tcellular organisms\tBacteria\tProteobacteria\t\t\t\t\t\tno rank\tno rank\tsuperkingdom\tphylum\t\t\t\t\t$

cluster=12330\troot\tcellular organisms\tBacteria\tTerrabacteria\tFirmicutes\tClostridia\tClostridiales\tClostridiaceae\tClostridium\tno rank\tno rank\tsuperkingdom\tno rank\tphylum\tclass\torder\tfamily\tgenus$

「\t」はタブ区切り文字で、「$」は行末です。

答え1

Awkを使用して2つのパスを作成します。

awk -F'\t' -v OFS='\t' 'FNR==NR {if (NF>a) {a=NF}; next} NF<a{$a=""} 1' file file

これにより、次の場所に追加タブが追加されます。終わり不足しているフィールドを持つ行。


あなたの正確なサンプルデータに基づいて、あなたはプログラムで解決できない問題に対処しているようです。値が正しい列にあることを確認するために途中で追加のタブを追加する必要がある場合は、no_rankより素晴らしいロジックが必要です。

答え2

使用ミラー:同様の質問に答えたことがあります。ここでCSVただし、この場合、ヘッダー行には最大長がすでに提供されているため、他の場所で検索する必要はありません。

この場合、最大長は他の場所にあり、私ができる最善は次のとおりです。

cat in.dat | mlr --nidx --fs tab --nidx put -q '
  @maxnf = max(@maxnf, NF);
  @records[NR] = $*; # Retain
  @counts[NR] = NF;

  end {
    for (i in @records) {
      @record = @records[i];
      for (j = @counts[i] + 1; j <= @maxnf; j += 1) { # add extra fields
        @record["x".j] = "";
      }
      emit @record;            # insert into the output record stream
    }
  }
'

アイデアは、レコードのリストと最大NFを維持し、それをエンドブロックで処理することです。これはヘッドの機能を使用することに注意してください(最新の4.5.0バージョンではありません)。

関連情報