その最初の行の内容に基づいて列を検索する

その最初の行の内容に基づいて列を検索する

TSVしたがって、次のファイルがあります。

Hello world how are you
1 2 3 4 5
6 7 8 9 0

(上記の手紙のおもちゃの例では、各行のすべての内容をスペースで区切っています。)

私の目標は、「how」と「are」を含む列を最初の行値として取得することです。したがって、出力は次のようになります。

how are
3 4
8 9

問題は、これらのパターン(「どのように」や「is」)がどの列に表示されるのかわからないことです。たとえば、TSVファイルは実際には次のように配置できます。

Hello how world are you
1 3 2 4 5
6 8 7 9 0

たとえば、私はこれを処理する方法を知っていますがpython(ファイルを変更して必要な行を選択するだけです)、シェルでこれを実行したいのです(理由のため)。問題はどうするか分からないということです。コマンドラインユーティリティを使用して転置も可能であることを知っています(例を参照)。ここ)しかし、可能であれば、そのような大きなコードは避けたいと思います。私の初期の単純な解決策は単にgrep「どのように」と「is」でしたが、それは明らかにファイル全体を返すので、それはブロックされ続けます。

どんな助けやアドバイスにも感謝します!

編集:このコンピュータに新しいツールをインストールする権限がないことに注意してください。私はそれが実際に何を提供しているのか分からない。役立つ場合はこれですScientific Linux 7.3 (Nitrogen)

答え1

使用csvtool1:

csvtool -t ' ' -u ' ' namedcol how,are file

-t Input separator char.
-u Output separator char.

 namedcol <names>
    Assuming the first row of the CSV file is a list of column headings,
    this returned the column(s) with the named headings.

^sudo apt install csvtool

答え2

awk最初の行に一致するキーワードがあることを確認し、列番号を記録してからその値を印刷できます。

#first line -> Select columns based on keyword
NR==1 {
  for (i = 1; i <= NF; i++) {
    if ( $i == "how" ) {col_how=i}
    if ( $i == "are" ) {col_are=i}
  }
}
#print selected columns including header line
NR>=1 {
  print $col_how, $col_are
}

たとえば、保存しscript.awkて実行します。

awk -f script.awk datafile

編集する:

移転やingのアイデアgrepも簡単に実装できます。

datamash transpose <datafile | grep 'how\|are' | datamash transpose

-t ' 'スペースを区切り文字として定義するために使用されます。ただし、非常に長いファイルの場合、RAMの制限が発生する可能性があります。ただし、ほとんどのシステムには標準でインストールできない場合があります。

答え3

$ cat tst.awk
BEGIN {
    cols = (cols == "" ? "how are" : cols)
    nf = split(cols,tgts)
    FS = OFS = "\t"
}
NR==1 {
    for (i=1; i<=NF; i++) {
        f[$i] = i
    }
}
{
    for (i=1; i<=nf; i++) {
        printf "%s%s", $(f[tgts[i]]), (i<nf ? OFS : ORS)
    }
}

$ awk -f tst.awk file
how     are
3       4
8       9

$ awk -v cols='are world you Hello' -f tst.awk file
are     world   you     Hello
4       2       5       1
9       7       0       6

関連情報