web-dev-qa-db-ja.com

変数にawkで列を表示させる

私はこの変数を持っています:

collumn=2

Awkを使用して、ファイルのjohnで始まる行の2列目で変更したい。

たとえば、このファイルではsample.txt

bill|copper|real|bruce
john|gold|fake|jhin
johny|silver|geniue|madrit

これは機能しません:

collumn=2
awk -F '|' /^jonh/ -v collumn="$2" sample.txt
echo "$collumn"

goldを印刷したい。

基本的に、変数の値をawkで変更します。

3
cater pilar

BashとAWKの2つの言語を使用しています。

Bashこれは your Shell )と AWK は両方とも プログラミング言語 、両方とも variables にデータを保存できます。 しかし シェルの変数AWKの変数 は完全に分離されています。さらに、AWKの変数は、AWKスクリプトの終了後に存在しなくなります。つまり、awkコマンドの実行が完了すると、AWK変数はなくなります。

var=valという形式のテキストを コマンドライン引数 としてawkコマンドに渡すことができます。これにより、変数がAWK に割り当てられます。シェル変数には一切影響しません。 -vオプション(-v var=valなど)を使用すると、awkコマンドに、AWKスクリプトを実行する前に変数を割り当てるように指示しますが、それでもシェル変数ではなくAWK変数です。

目標は、一致した行の特定の列のテキストを Shell変数に割り当てることです。出来るよ。 しかし、最初に、より簡単な問題を解決しましょう。このコマンドは、johnおよび displays で始まる行を検索しますそのような各行の2番目の列の。そのように開始する行が1つしかない場合は、1つのアイテムが表示されます。そのような行がない場合、何も表示されず、johnで始まる行が複数ある場合、複数の項目が別々の行に表示されます。

awk -F '|' '/^john/ { print $2 }' sample.txt

そのコマンドのAWKスクリプトは/^john/ {print $2}です。 単一引用符'')で囲み、awkコマンドに渡される前に シェルによって変更された ではなく、単一の文字列として扱われます。それ以外の場合、シェルはAWKスクリプトを5つと解釈します 別個の単語と演算子 シェル自体に対して( not AWK)、これは/^john/をAWKスクリプト。それ以降はすべてawkに渡すファイル名として扱われますが、これは機能しません。シェル また 展開 $2 で、結果に対して 単語分割 および ファイル名展開(グロビング) を実行します(ただし、$2二重引用符 で囲むと、質問のように分割やグロビングが防止されます)。あなたはそれらの事のどれも起こらせたくありません。一般に、AWKスクリプトを単一引用符で囲み、awkコマンドに忠実に渡されるようにすることをお勧めします。

質問に示されているsample.txtファイルを使用すると、このコマンドは次の出力を生成します。

gold
silver

1行ではなく、一致する2行からテキストを印刷します。 goldだけが必要なため、 start johnに一致するすべての行を一致させたくないと思われます。代わりに、おそらく最初の列のエントリがjohn正確にである行のみに一致させたいでしょう。 (問題のより単純なバージョンを最初に解決する利点の1つは、解決したい問題の正確な知識を絞り込むのに役立つことです。)最初の列エントリがである行のみを選択できます正確にjohnこのように:

awk -F '|' '$1 == "john" { print $2 }' sample.txt

表示されるもの:

gold

では、完全な問題を解決しましょう。シェル変数への割り当ては、AWKスクリプトでできることではありません。これはAWK言語の一部ではないだけでなく、awkコマンド シェルの一部として実装する必要があります を可能にするためです。これは、やりたいことを実行できないという意味ではありません。絶対に実行できます。これは、AWKコードを記述してシェル変数に割り当てるのではなく、シェル自体を使用して実行する必要があることを意味します。

変数に割り当てたい値を表示するawkコマンドがあります。そのため、シェルで command substitution を使用して、割り当てを実行できます。このコマンドは、それをentryというシェル変数に割り当てます(ただし、entryなど、columnの代わりに好きな名前を使用できます)。

entry="$(awk -F '|' '$1 == "john" { print $2 }' sample.txt)"

これは、シェル replaces$()と、その中のコマンドを実行することで生成される output ですべてが機能するためです。 コマンド置換 です。このようなシェル変数を割り当てるときは、 not =記号の周りにスペースが必要であることに注意してください。

(ちなみに、テキストjohnは効果的に引用されていないように色付けされていることに気付くかもしれません。これは実際にはこのWebサイトで構文ハイライトを提供するソフトウェアのバグです。外側の""であるため、内側の""$()の中にあることはわかりません。しかし、実際にコマンドを実行するときにはこれは問題になりません。)

以下を実行することで、goldentryシェル変数に割り当てられたことを確認できます。

echo "$entry"

それは表示されます:

gold

AWK言語の変数の詳細については、このセクションを参照してください 6.1.3変数 in Gawk:Effective AWK Programming 、これはGNUの公式ドキュメントです_ awk(gawk)。 GNU awkを文書化していますが、GNU awkに固有のものと、AWK言語の他の実装でも使用できるものについて説明しています。 Ubuntuシステムのawkコマンドは、インストールしたソフトウェアとその設定方法に応じて、 mawk または gawk のいずれかになります。どちらかを確認する1つの方法は、awk -W versionを実行することです。

2
Eliah Kagan