開始列、増分値、およびファイル名をランタイム・パラメーターとして渡して、ファイル内のすべてのN列を印刷するスクリプトを作成しようとしています。以下は私のスクリプトです。
file=$1
st=$2
inc=$3
echo $file
echo $st
echo $inc
awk '{for (i = $st; i <= NF; i += $inc) printf ("%s%c", $i, i + $inc <= NF ? " " : "\n");}' $file
結果が得られません。誰でも私を助けることができますか?私の入力は次のようになります。script.sh file_name 1 4
よろしくお願いします。 :-)
答え1
シェル変数は自動的に変数になりませんawk
(変数はthフィールドではないとマークされてawk
います)。シェル変数をに渡す場合は、簡単な方法は環境を使用することです。var
$var
var
awk
#! /bin/sh -
file=$1
ST=$2
INC=$3
export ST INC
awk '
{
sep = ""
for (i = ENVIRON["ST"]; i <= NF; i += ENVIRON["INC"]) {
printf "%c%s", sep, $i
sep = OFS
}
printf "\n"
}' < "$file"
シェル変数を引用し、任意のファイル名を引数として使用しないでください(一部はaまたは特別に呼び出されたファイル名awk
として扱うため)。=
-
変数を渡すもう1つの方法は、awk
awkスクリプトの後に-v awkvar="$shellvar"
またはパラメータを使用することです。ただし、エスケープシーケンスが拡張され(改行文字など)、GNU 4.2以降awkvar="$shellvar"
では任意の文字列と一緒に使用することはできません。\\
\
\n
awk
で始まり@/
終わる値は/
特別に扱われます。POSIXモードを除いて。
awk -v st="$st" -v inc="$inc" '{for (i = st; i <= NF; i += inc)...}' < "$file"
または
awk '{for (i = st; i <= NF; i += inc)...}' st="$st" inc="$inc" < "$file"
この変数には数字のみが含まれるので(バックスラッシュはありません)、ここでは問題ありません。
何をしてもしないでください。
awk 'for (i = '"$st"'; i <= NF; i += '"$inc"')...'
言及する必要がない
awk 'for (i = '$st'; i <= NF; i += '$inc')...'
つまり、シェルがに渡されたコードの値と変数を拡張するようにします$st
。これにより、コマンド注入の脆弱性(たとえば、次の値)が発生する可能性があります。$inc
awk
st
system("reboot")
答え2
あなたのスクリプトを修正し、今動作します。 2つのエラーがあります。 (a)シェル変数を手動でawkに渡す必要があります(これは構文を使用して実行されます)。(b)変数を表すためにそれを使用しない-v awk_var="$shell_var"
でください。シンボルはフィールド位置にのみ使用されます。$
$
file=$1
st=$2
inc=$3
echo $file
echo $st
echo $inc
awk -v st="$st" -v inc="$inc" '{for (i = st; i <= NF; i += inc) printf ("%s%c", $i, i + inc <= NF ? " " : "\n");}' $file