GNU/Linux >> Linux の 問題 >  >> Linux

データがフィールドに分割されているテキストファイルの行を抽出/変更するにはどうすればよいですか?

コマンドラインからフィールドベースのデータを操作するにはどうすればよいですか?例

  • N番目のフィールドがfooである行のみを印刷するにはどうすればよいですか。 ?
  • N番目のフィールドがfooではない行のみを印刷するにはどうすればよいですか。 ?
  • N番目のフィールドがfooと一致する行のみを印刷するにはどうすればよいですか。 ?
  • フィールドNをfooに変更するにはどうすればよいですか。 ?

* nixシステムでフィールドベースのデータを操作するのを容易にする標準的なアプローチまたはツールセットはありますか?

承認された回答:

フィールドを処理するときに使用できる基本的なアプローチは2つあります。i)フィールドを理解するツールを使用する。 ii)正規表現を使用します。 2つのうち、前者は通常、より堅牢でシンプルです。

* nixで一般的に利用可能なツールの多くは、フィールドを処理するように明示的に設計されているか、フィールドを容易にするための巧妙なトリックを備えています。

1。フィールドを理解するツールを使用する

1.1 awk

ここでの古典的なツールはawkです 。各入力行が自動的にフィールドに分割されます(フィールド区切り文字はデフォルトでは空白ですが、 -Fを使用して変更できます。 フラグ)、フィールドは awkで使用できます $ nとしてのスクリプト ここで、 n フィールド番号です。最初のフィールドは$1です 、2番目の $ 2 など

  • 3番目のフィールドがfooである行を印刷します 。

    awk '$3=="foo"' file
    

    区切り文字をに変更します

    awk -F":" '$3=="foo"' file
    

    awkのデフォルトのアクション 印刷することです。したがって、上記のコマンドは、3番目のフィールドが fooであるすべての行を出力します。 。 -Fを使用する場合 、任意のフィールドセパレータを設定でき、正規表現を使用することもできます。

  • 3番目のフィールドがfooではない行のみを印刷するにはどうすればよいですか。 ?

    awk '$3!="foo"' file
    
  • 3番目のフィールドがfooと一致する行のみを印刷するにはどうすればよいですか。 ?

    パターンに一致するフィールドを探しているだけの場合(たとえば、 foo foobarに一致します )、を使用します ==の代わりに :

    awk '$3~/foo/' file
    
  • 3番目のフィールドがfooと一致しない行のみを印刷するにはどうすればよいですか。 ?

    awk '$3!~/foo/' file
    
  • 3番目のフィールドをfooに変更するにはどうすればよいですか。 ?

    awk '$3="foo"' file
    

1.2 Perl

もう1つの選択肢はperlです ワンライナー。 awkと同様に、Perlはフル機能のスクリプト言語ですが、スクリプトを入力として受け取るコマンドラインプログラムとして実行することもできます。その動作はコマンドラインスイッチによって変更されます。この質問に最も関連するのは次のとおりです。

  • -e perlのスクリプト 実行する必要があります;
  • -n :入力ファイルを1行ずつ読み取ります;
  • -p -e で指定されたスクリプトを適用した後、各入力行を出力します;
  • -l <​​/ code> :各入力行から末尾の改行を削除し、各 printに改行を追加します 電話;
  • -a :awk-mode、各入力行を配列 @Fに分割します;
  • -F -aのフィールドセパレータ 。

awkとの重要な違い そのperl-a スイッチはファイルを配列に分割します。 Perlでは、配列は1ではなく0から始まります。これは、2番目のフィールドが実際には $ F [1]であることを意味します。 $ F [2]ではありません 。これらすべてを念頭に置いて、 perl 上記に相当するものは次のとおりです。

  • 3番目のフィールドがfooである行を印刷します 。

    perl -ane 'print if $F[2] eq "foo"' file
    

    区切り文字をに変更します

    perl -F":" -ane 'print if $F[2] eq "foo"' file
    

    awkとは異なり 、 perl フィールド区切り文字として正規表現を使用することはできません。特定の文字または文字列である必要があります。

  • 3番目のフィールドがfooではない行のみを印刷するにはどうすればよいですか。 ?

    perl -ane 'print unless $F[2] eq "foo"' file
    
  • 3番目のフィールドがfooと一致する行のみを印刷するにはどうすればよいですか。 ?

    perl -ane 'print if $F[2]=~/foo/' file
    
  • 3番目のフィールドがfooと一致しない行のみを印刷するにはどうすればよいですか。 ?

    perl -lane 'print unless $F[2]=~/foo/' file
    
  • 3番目のフィールドをfooに変更するにはどうすればよいですか。 ?

    これはPerlではもう少し面倒です。通常のアプローチは、 @Fの値を変更することです。 配列してから、配列を出力します。スペースで区切られた単純なファイルを使用すると、これは簡単です。

    perl -lane '$F[2]="foo"; print "@F"' file
    

    別の区切り文字を使用すると、 joinする必要があります アレイ。それ以外の場合は、スペースで区切られて印刷されます:

    perl -F: -lane '$F[2]="foo"; print join ":",@F' file
    

2。正規表現を使用する

ここでの考え方は、行内のターゲット文字列の位置を定義する正規表現(略して「regex」)を使用することです。たとえば、フィールドがで区切られているファイルの場合 、1番目のまでのすべてを照合することで、2番目のフィールドを見つけることができます。 (最初のフィールド)次に2番目のフィールドを探します:

^[^:]*:[^:]*:

この正規表現の意味:

  • ^ :行の先頭;
  • [^] :否定された文字クラス。 [^:] 以外のもの:」を意味します 「;
  • * :前のパターンの0以上;
  • :リテラル;

まとめると、これは最初の [^:] *を意味します は最初のフィールドで、2番目は2番目のフィールドです。明らかに、これは14番目のフィールドを探している場合はあまり実用的ではありませんが、より単純なものには役立ちます。では、これをどのように実装してデータを操作するのでしょうか。これを行うことができるさまざまなツールがあります。これらの例では、 sedを使用します ただし、 awkでも非常によく似たことができます。 、 perl またはpython

  • 2番目のフィールドがfooである行のみを印刷するにはどうすればよいですか。 ?

    sed -n '/^[^:]*:foo:/p' file
    

    -n 通常の出力と/regex / pを抑制します 「正規表現が一致したすべての行を印刷する」という意味です。

  • 2番目のフィールドがfooではない行のみを印刷するにはどうすればよいですか。 ?

    sed '/^[^:]*:foo:/d' file
    

    上記の論理的な逆。ここでは、 / regex / d 「正規表現が一致する行をすべて削除する」という意味です。

  • 2番目のフィールドがfooと一致する行のみを印刷するにはどうすればよいですか。 ?

    sed -n '/^[^:]*:[^:]*foo/p' file
    
  • 2番目のフィールドがfooと一致しない行のみを印刷するにはどうすればよいですか。 ?

    sed '/^[^:]*:[^:]*foo/d' file
    
  • 2番目のフィールドをfooに変更するにはどうすればよいですか。 ?

    sed 's/([^:]*:)[^:]*/1foo/' file 
    

    または、 sed以降 置換は、単純な数値フラグを使用して繰り返すことにより、パターンの発生に直接対処できます。

    sed 's/[^:]*/foo/2' file
    

Linux
  1. 複数行をカンマ区切りの 1 行にする

  2. 1 つのテキスト ファイルを複数の *.txt ファイルに分割する方法は?

  3. Linux/bashでバイナリファイルのテキスト部分を抽出するには?

  1. Vimモードとは何ですか?それらを変更する方法は?

  2. UNIXで、ファイルの10行目から15行目を別のファイルにコピーする方法は?

  3. 文字列の最初の出現から始めて、大きなファイルからテキストを抽出する方法は?

  1. テキストファイル内の重複行を削除するにはどうすればよいですか?

  2. Sedを使用してテキストファイルから複数のランダム行を削除する方法は?

  3. タブ区切りのテキスト ファイル内のフィールドの一意の値の数をカウントする方法は?