目的の列をすべて選択するのではなく、実際の列を削除する

目的の列をすべて選択するのではなく、実際の列を削除する

私はこれが簡単な質問であることを知っていて、以前はいくつかの分野で答えを受けましたが、awk、sed、grepなどを使用するたびに、必要な列を選択して印刷するのを見ました。必要な列の数が不明で、特定の列が不要な場合は、不要な列をどのように削除しますか?

不要な列の前にある列を選択し、不要な列の後にあるn列を選択しますか? n番目の列を削除する簡単な関数はありませんか?

好奇心から出てきたので、例はありませんが、必要に応じて例を挙げることができます。

答え1

[OK]、[切り取り] コマンドを使用できますが、まだその列を削除するわけではありませんが、目的の列を選択し、無制限の列オプションがあります。したがって、列2を選択し、列4以降のすべての列を選択したい場合、1つの解決策は次のとおりです。

cut -f 2,4- file.txt    

それでも実際の削除コマンドがあるかどうかを知りたいです。

答え2

awk実際、行からフィールドを削除する機能はありませんが、特定の列を空の文字列に設定できます。

ただし、列(列5と7など)を削除する一般的な方法があります。

awk '{$5=$7="" ; $0=$0;$1=$1}1'

$ 0を自分に設定$0=$0;$1=1し、$ 1を自分に設定します。これは、追加のフィールド区切り文字(たとえば、現在空の$ 5フィールドと$ 7フィールドの直後にある区切り文字)を削除する副作用です。

注:これはまた、$ 0のすべてのフィールド区切り文字を現在設定されている出力フィールド区切り文字(OFS)に変換します(たとえば、デフォルトのFSおよびOFSを使用すると次のように変換されます)。複数のタブとスペースフィールド間で一つスペース)

そしてperlはるかに簡単です。それするsplice()配列から列を削除する関数()があります。

perl -lane 'BEGIN{$,=" "}; splice(@F,4,1); splice(@F,5,1); print @F'

$,=" "出力フィールド区切り文字を単一のスペースに設定します。

メモ:

  1. Perl配列は1ではなく0から始まります。@F[4]第五列も同様です。

  2. これにより列5が削除されるため、削除したい2番目の列(列7)は現在列6になり、2番目の列は削除されspliceます@F[5]

ここで潜在的な混乱を避けるために、列を逆順に削除してください。

perl -lane 'BEGIN{$,=" "}; splice(@F,6,1); splice(@F,4,1); print @F'

あるいは、ループを使用することもできます。

perl -lane 'BEGIN{$,=" "}; foreach $c (7,5) {splice(@F,$c-1,1)}; print @F'

しかし、ちょうど削除したい場合最初または最後shift @F列には、またはを使用できますpop @F

出力:

次の入力を使用すると:

1 2 3 4 5 6 7 8 9 10
10  9   8   7   6   5   4   3   2   1
a b c d e f h i j k

みんな上記のスクリプトは、次の出力を生成します。

1 2 3 4 6 8 9 10
10 9 8 7 5 3 2 1
a b c d f i j k

答え3

列の意味によって異なります。実際に区切られたフィールドではなく文字列を参照する場合、あいまいなコム削除する開始列または一連の列の開始列と終了列を指定できます。 1回の呼び出しで連続していない列を削除できません

答え4

私はcutコマンドがあなたに役立つと思いますか?

以前の回答でこれを見つけました。https://stackoverflow.com/questions/13690461/using-cut-command-to-remove-multiple-columns

cutコマンドに関する追加情報: http://www.computerhope.com/unix/ucut.htm https://en.wikipedia.org/wiki/Cut_(Unix)

関連情報