前に0を含む変数がありますが、この変数と同じ変数に1を加えた値をgrepしたいと思います。何度も試しましたが、エラーが発生しました。これが私がしたいことです:
read var
newvar=$(($var +1))
grep '$var' /some/dir
grep '$newvar' /some/dir
私のコードに何か問題があると思います。私も次のようないくつかのテストを試しました。
#!/bin/bash
echo "enter number"
read number
newnumber=$(($number + 1))
echo "$newnumber"
これでエラーが発生しましたvalue too great for base (error token is
。私がこうすれば:
#!/bin/bash
echo "enter number"
read number
number=""
newnumber=$(($number + 1))
echo "$newnumber"
これにより常に1が出力されます。
私の試みには何の問題があり、私がしたいことをどのようにすることができますか?
答え1
無効な引用符を使用しています。一重引用符は''
式(および以前の形式)の拡張を防ぎます。代わりに二重引用符を使用してください。この場合、数字であると確信している場合は必要ありません。$
$var
$(command)
`command`
""
どの引用符。
2番目の質問には...前に0を使用しますか?これは8進数を表すため、数値の合計は機能8
し9
ません。
答え2
ギグドラゴン最初の試みが失敗した理由をすでに説明しました。実行しようとしているタスクに関するいくつかの追加のヒントは次のとおりです。
似たような数字を探しているなら、それを42
一致させたいのですが、042
またはは一致しません。これを達成するには、より進化した正規表現だけが必要です。前にゼロのない数字(整数、正数、小数表現)が含まれている場合は、前に行の先頭または数字以外の文字が続く文字とそれに続く同じ文字を探します。前にゼロが追加で許可されます。このオプションは、現代の正規表現構文を使用していることを示します。1042
421
$newnumber
$newnumber
0*
-E
grep
grep -E "(^|[^0-9])0*$newnumber(\$|^[0-9])" /path/to/file
$((10#$newnumber))
Bashの前にゼロが続く可能性がある数値を解析するには、強制10進解釈を使用できます。他のシェルでは、状況は少し複雑です。特定のプレフィックスなしで変数値を取得するシェル構造${var#prefix}
に似たサフィックス構造がありますが、次のような「可能な最長文字シーケンス」を${var%suffix}
指定する方法はありません。0
削除するプレフィックス。ただし、2 つのステップで実行できます。まずvar
、先行ゼロ以外の部分を取得し、それを削除されたプレフィックスとして使用します。 0の前に来ない部分は、ゼロvar
以外のものから始まる最も長いサフィックスです。つまり${var%%[!0]*}
、二重精度は%
パターンに一致する最も長いサフィックスを取ることを意味し、単精度は%
最短サフィックスを取ることを意味します。
read number
number=${number#${number%%[!0]*}}
追加の説明:grep REGEXP /some/file
単一ファイル検索/some/file
。ディレクトリ内のすべてのファイルを検索するには、シェルにファイルリストを作成させます。ディレクトリとgrep REGEXP /some/dir/*
そのサブディレクトリ内のすべてのファイルを再帰的に検索するには、オプションを渡して再帰的-r
にgrep
作成しますgrep -r REGEXP /some/dir
。
答え3
Geekosaurが言ったように、間違った引用符を使用しています。シェルに値への変数参照を拡張させるには、二重引用符を使用します。
第二に、二重括弧内の数学が間違っています。 $(())構文内の変数参照には$は必要ありません。
#!/bin/bash
echo "enter number"
read number
newnumber=${number#${number%%[!0]*}}
newnumber=$((newnumber + 1))
echo "$number changes to $newnumber"
これら2つの変更は元のバージョンでも効果がありました...
read var
newvar=${var#${var%%[!0]*}}
newvar=$((newvar + 1))
printf -v newvar "%02d" "$newvar"
grep "$newvar" /some/dir
修正する出力形式を指定する行を追加しましたprintf
。
アップデート2ゼロで埋められた数値入力に対する修正が追加されました。今これは完全な例になります。
答え4
いくつかの部分的な答え:
前にゼロの付いた数値 v1 を処理する方法:
newvar=$(printf '%s + 1\n' "$var" | bc)
または等しく、
newvar=$(bc <<< "$var + 1")
bc
前に0が付いた数字は8進数と見なされないためです。
私が知る限り、bc
シェルエスケープ機能がないように見えるので、これはコード注入の脆弱性を生成しません。 (おそらく何か見落としているようです。)質問には「bash only」と書かれていません。
前にゼロの付いた数値 v2 を処理する方法:
newvar=$((1$var - 10000 + 1))
明らかに、これはトリックを使用しているようです。八織がしたいこと:1
プレフィックス0042
文字列演算として、10042
10進数で処理された文字列を取得します。この構成では〜しなければならないとは、2つの別々の単位に解析され、接続するように含まれます $
。$var
1
$var
入力値が4桁であることがわかっている場合(たとえば 0042
)、上記のコマンドをそのまま使用します。異なる長さがある場合(事前に知られている)、10000
上記の内容1
の後に適切な数のゼロが来るように変更してください。
もしあなたならいいえ長さを事前に知ってください。
pow10="1$(printf "%0${#var}d" 0)"
または
pow10="1$(printf '%0*d' "${#var}" 0)"
これは、デフォルトで数字が4桁の場合(たとえば)を生成する0042
ために使用され、これを得るために前にaが追加されます。それからprintf '%04d' 0
0000
1
10000
newvar=$((1$var - pow10 + 1))
結果にnewvar
先行ゼロを追加するには:
マークの答え使用できることを示します。
printf -v newvar '%04d' "$newvar"
または等しく、
newvar=$(printf '%04d' "$newvar")
$newvar
合計が4桁になるように前にゼロを十分に追加します。長さが事前にわからない場合は、前のセクションの技術を使用できます。
newvar="$(printf "%0${#var}d" "$newvar")"
または
newvar="$(printf '%0*d' "${#var}" "$newvar")"