私はこの変数を持っています:
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で変更します。
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サイトで構文ハイライトを提供するソフトウェアのバグです。外側の"
"
であるため、内側の"
"
が$(
)
の中にあることはわかりません。しかし、実際にコマンドを実行するときにはこれは問題になりません。)
以下を実行することで、gold
がentry
シェル変数に割り当てられたことを確認できます。
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
を実行することです。