web-dev-qa-db-ja.com

コマンドライン:出力から部分文字列を抽出する

コマンドSayStuffを実行するとします

$ SayStuff

そして出力は

Watermelons and cucumbers

今。たとえば、出力から部分文字列cucumbersを抽出して、何かにパイプしたいとします。
これをプログラムで行う方法は、出力を区切り文字Spaceで配列に分割し、ArrayName[2]で参照することです。私はシェルスクリプトにかなり慣れていないため、半暗号のcutの例を掘り上げることに成功しただけで、どれも意味がありませんでした。

何か案は?

27
krystah
$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers

-d ' 'は、スペースで分割するようにcutに指示します。 -f 3は3番目の列を選択します。

awkを使用することもできます。これは、すでにスペースに基づいて分割し、列を$1$2、…として使用できるようにします。

$ echo "Watermelons and cucumbers" | awk '{ print $3 }'
cucumbers
34
slhck

@slhckですでに指定されているオプションの1つを使用する可能性がありますが、これを行う方法がいくつかあります。

  1. 他の言語と同じように配列を使用する:

    _$ foo=( $(SayStuff) ) 
    $ echo ${foo[2]}
    cucumbers
    _

    var=()は配列を宣言し、$(command)はコマンドの出力を保存します。したがって、foo=( $(SayStuff) )SayStuffの出力を配列fooに格納し、その後、echoは_${foo[2]}_を含む3番目の要素です。

  2. sed

    _$ SayStuff | sed 's/.* \(.*\)/\1/'
    cucumbers
    _

    sedコマンドは(_s///_)すべてを最後のWordで置き換えます。正規表現は、スペースまでのすべてに一致します(_.*_)。最後のスペースまでのすべてに一致し、最後のWordをキャプチャします_(\(.*\)_。 Wordはキャプチャされているので、_\1_として参照できます。

    シンプルなバージョン:

    _$ SayStuff | sed 's/.* //'
    cucumbers
    _
  3. bash

    _$ foo=$(SayStuff); echo ${foo##* } 
    cucumbers
    _

    これはbashの文字列操作機能を使用します。詳細については here を参照してください。

  4. もっとbash

    _$ SayStuff | while read a b c; do echo $c; done
    cucumbers
    _
  5. Perl、もちろん、これを行うには多くの方法があります。

    _$ SayStuff | Perl -lane 'print $F[$#F]'
    cucumber
    _

    _-a_は、Perlawkのように動作させ、空白で行を分割し、配列_@F_に保存します。次に、_@F_の最後の要素を出力します(_$#F_は_@F_の要素の数です)。 _-l_は、各printステートメントに改行を追加するようにPerlに指示します。_-n_ STDINを1行ずつ処理する必要があること、および_-e_は、コマンドライン。

    _$ SayStuff | Perl -pe 's/.* //'
    cucumber
    _

    オプションについては上記で説明しましたが、最後のスペースまですべてを削除して印刷しています(_-p_)。

    _$ Perl -le 'print $ARGV[$#ARGV]' $(SayStuff)
    cucumbers
    _

    ここでは、_Watermelons and cucumbers_を引数として渡し、Perlが_@ARG_配列に保存するため、_@ARG_の最後の要素を出力します。

  6. 策略。これはsedを使用してスペースを改行に変換し、次にtailを使用して最後の行のみを出力します。

    _$ SayStuff | sed 's/ /\n/g' | tail -n 1
    cucumbers
    _
  7. 一致した文字列のみを出力する_-o_を使用したgrepおよび正規表現。

    _$ SayStuff | grep -Po '\w+$' 
    cucumbers
    _
  8. 浮気

    _$ SayStuff | grep -o cucumbers
    cucumbers
    _
15
terdon

ここにいくつかの説明があります:

Usage: cut OPTION... [FILE]...

Print selected parts of lines from each FILE to standard output.

   -d, --delimiter=DELIM
          use DELIM instead of TAB for field delimiter

   -f, --fields=LIST
          select only these fields;  also print any line that contains  no
          delimiter character, unless the -s option is specified

したがって、3番目のフィールドが必要で、スペース「」で区切られている場合は、

$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3  
cucumbers

[〜#〜] last [〜#〜]フィールドが必要な場合は、おそらくawkを使用する必要があります。
この場合、次のようになります。

$エコー "スイカとキュウリ" | awk '{print $ NF}'
キュウリ

awkでは、NFは行のフィールド数なので、$NFは、行の最後のフィールドを意味します。

2
zeridon