500列のファイルがあります。他のファイルのリストに名前が記載されているいくつかの列を削除する必要があります。例えば
fileA
:
id1 id22 id43 id4 id5 id6 id7 id68 id9 id10 id11
TT AA AG TC TT AA AG TC DD AA CC
TT AC GG TC TT AG AG TC AD AA DC
fileB
:
id1
id5
id10
id68
希望の出力:
id22 id43 id4 id6 id7 id9 id11
AA AG TC AA AG DD CC
AC GG TC AG AG AD DC
答え1
これを一行と呼びたいかどうかはわかりませんが、非常に基本的なツールを使用してすぐに実行できます。
cut -d' ' -f $(head -n 1 fileA | tr -s ' ' '\n' | cat -n | grep -wvf fileB | cut -f 1 | tr '\n ' ',' | sed -e 's/,$//' -e 's/^,//') fileA
説明する:
このcut
コマンドは、cut -d' ' -f [...] fileA
単にスペースを区切り文字として使用し、-d' '
保持するフィールドを選択します-f
。次に、動的に生成されたカンマ区切りインデックスのリストに基づいて、どのフィールド/列を使用するかについて質問があります。
head -n 1 fileA
ヘッダー行のみを選択し、tr -s ' ' '\n'
すべてのスペースを改行に変更し(-s
複数のスペースを単一のスペースに圧縮して)、cat -n
このリストに行番号を追加します。
この行番号は元の列番号と同じであるため、残りの行番号を選択する必要があります。削除リストのヘッダーを反転してgrep -wvf fileB
(同時に削除されないようにするために使用されます)、このリストが行番号のみを指すようにし、改行文字をコンマ()に変換してカンマ区切りリストを提供します。残りの列数です。ただし、最後のステップでは、リストの前後にコンマがあるため、を使用して削除する必要があります。これで外部フィールドのリストが完成しました。grep
-w
id1
id11
cut -f 1
tr '\n' ','
sed -e 's/,$//' -e 's/^,//'
cut
まず、カウンターチェックで内部パイプラインを別々に実行することもできます。追加の列インデックスは結果に影響を与えません。