特定のテキストを含む列を削除する

特定のテキストを含む列を削除する

次の特定のテキストを含む列を削除するオプションを探しています。

「ディディ」

aaa bbb ccc ddd eee fff
1   2   3   4   5   6
2   3   4   5   6   0

したがって、出力は次のようになります。

aaa bbb ccc eee fff
1   2   3   5   6
2   3   4   6   0

私は列4を削除し、同じことを行う簡単なオプションがあることを知っていますが、私の* .csvファイルはソートされません。どんなアイデアがありますか?

ベストアンサー1

sed正しいツールではありません。努力するawk

$ awk -v OFS='\t' 'NR==1{for (i=1;i<=NF;i++)if ($i=="ddd"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' file
aaa     bbb     ccc     eee     fff
1       2       3       5       6
2       3       4       6       0

削除したい文字列(ddd この例では)が最初の行のフィールドとして表示されるとします。

どのように動作しますか?

  • -v OFS='\t'

    これにより、出力フィールド区切り文字がタブに設定されます。他のものを使用している場合は、この設定を変更してください。

  • NR==1{for (i=1;i<=NF;i++)if ($i=="ddd"){n=i-1;m=NF-(i==NF)}}

    これにより、最初の行のすべての列が検索されます。 (マイナス1)として列番号をddd変数に保存しますn

    m最後の列の番号にも設定されますが、i最後の列の場合に設定されますNF-1

  • for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS

    dddこれにより、最初の行に表示されるフィールドがスキップされ、すべてのフィールドが印刷されます。

    i+=1iループを通過するたびに1ずつ増加します。各ループで1i+=1+(i==n)ずつ増加しますi。ただし、i==nこの場合はi2ずつ増加します。これは右側の列をスキップする効果があります。

    printf "%s%s",$i,i==m?ORS:OFS最後の列であるかどうかに応じて、i列区切り文字OFSまたは行区切り文字の後に続く列を印刷します。ORSi

複数行

このようなコマンドを複数行で書くことを好む人のために:

awk -v OFS='\t' '

NR==1{
    for (i=1;i<=NF;i++)
        if ($i=="ddd") {
            n=i-1
            m=NF-(i==NF)
        }
    }

{
    for(i=1;i<=NF;i+=1+(i==n))
        printf "%s%s",$i,i==m?ORS:OFS
}

' file

カンマ区切りファイルの使用

入力と出力をコンマで区切るには、入力フィールド区切り記号(使用-F)と出力フィールド区切り記号を変更する必要があります。たとえば、次の入力ファイルを考えてみましょう。

$ cat file2
aaa,bbb,ccc,ddd,eee,fff
1,2,3,4,5,6
2,3,4,5,6,0

次に、次を使用します。

$ awk -F, -v OFS=, 'NR==1{for (i=1;i<=NF;i++)if ($i=="ddd"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' file2
aaa,bbb,ccc,eee,fff
1,2,3,5,6
2,3,4,6,0

おすすめ記事