awkの構文エラー

awkの構文エラー
#!/usr/bin/awk

userinput='Hello World!'
userinput=$userinput awk '
    BEGIN {
        s = ENVIRON["userinput"] "\n"
        n = length(s)
        while (1)
            printf "%s", substr(s,int(1+rand()*n),1)
    }'

上記のコードを実行するたびに、次のエラーが発生します。

awk:コマンド。行1:pass.awk
awk:cmd。行1:^構文エラー

#!/usr/bin/awk

awk '{
        s = $0 "\n"
        n = length(s)
        while (1)
            printf "%s", substr(s,int(1+rand()*n),1)
    }'

awk:コマンド。行1:pass.awk
awk:cmd。行1:^構文エラー

両方とも同じエラーが発生しました。ただし、このコードを記述して端末で実行してもエラーは発生しません。これは私にとって少し奇妙です。なぜなら私は初心者だからですawk。これがオタイであるかどうかはよくわかりません。pass.awkこのようにしてファイル名を.Runとして保存しましたawk pass.awkawk pass.awk hello

答え1

これには2つの問題があります。まず、スクリプトを作成するにはファイルが必要なため、Shabanで使用する必要があります。awkこれを使用することは、スクリプトの内容をそのまま使用できる回避策です。バラより:-fawkawkman awk

   -f progfile
             Specify  the pathname of the file progfile containing an awk
             program. A pathname of '-' shall denote the standard  input.
             If multiple instances of this option are specified, the con‐
             catenation of the files specified as progfile in  the  order
             specified  shall be the awk program. The awk program can al‐
             ternatively be specified in the command line as a single ar‐
             gument.

したがって、awkShebangで通訳として使用するには、次のものが必要です。

#!/bin/awk -f

BEGIN{print "hello world!"}

あなたが持っているのは呼び出されるシェルスクリプトなawkので、シェルshebangが必要です。

#!/bin/sh

awk 'BEGIN{ print "Hello world!"}'

次の問題は、変数にスペースがありますが、引用符なしで変数を使用していることです。シェルスクリプトでは常に変数を引用してください!あなたが望むものは次のとおりです。

userinput='Hello World!'
userinput="$userinput" awk '...

最初の(シェル)スクリプトの作業バージョンは次のとおりです。

#!/bin/sh

userinput='Hello World!'
userinput="$userinput" awk '
    BEGIN {
        s = ENVIRON["userinput"] "\n"
        n = length(s)
        while (1)
            printf "%s", substr(s,int(1+rand()*n),1)
    }'

スクリプトが決して終了しないことを意味while (1)し、無限ループです。

実際のawkスクリプトである2番目のスクリプトは次のとおりです。

#!/usr/bin/awk -f

{
  s = $0 "\n"
  n = length(s)
  while (1)
    printf "%s", substr(s,int(1+rand()*n),1)
}

答え2

最初の行でawkの代わりにシェルインタプリタを呼び出すようにします。

#!/usr/bin/env bash

答え3

デフォルトでは、awkはプログラムコードを含む文字列をコマンドラインの最初の引数として期待します。例えば

awk 'BEGIN{ print "hello" }'

のみ印刷されますhello。だから走るなら

awk pass.awk

pass.awkawkコードとして解釈しようとしています。 dot は有効な awk 構文ではないため、エラーが発生します。

ファイルからコードを読むには、awk -f foo.awk@terdonの答えに示すようにを使用してください。 (ハッシュバンラインを修正し、図のようにシェルスタブを削除する必要があります。)

関連情報