単純なbashスクリプトがあります。
input_dir="`dirname $1`/`basename $1`/"
output_dir="`dirname $2`/`basename $2`/"
ext=$3
...
...
...
echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/'" "$output_dir"*.$ext`
$N
問題は、一致グループがスクリプトのコマンドライン引数と競合するため、機能しないことです。この問題をどのように解決できますか?
答え1
質問に代わる置換が発生しないように、リテラル文字列の周りに単一引用符を使用してください。この文字列に一重引用符を使用する必要がある場合は、入力してください'\''
。
echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`
コードに他の問題があります。変数置換(および$1
)$2
またはコマンド置換(たとえば)の結果は、`rename …`
結果に対してトークン化およびワイルドカード割り当てを実行するシェルによって解析されます。変数置換とコマンド置換には常に二重引用符を使用してください。知らない場合は無視する必要があります。また、バックティックはシェルに依存する厳しい方法でネストされた引用符を処理するため、使用しないでください。博物館を除くすべてのシェルは、より健全な$(…)
構文をサポートします。また、aを呼び出すときにaを使用する必要があり--
、aで始まる場合はオプションのように見えます。dirname
basename
$1
$2
-
input_dir="$(dirname -- "$1")/$(basename -- "$1")/"
output_dir="$(dirname -- "$2")/$(basename -- "$2"/)"
ext="$3" # here it would be ok to omit the quotes, but if you're unsure of the rules, put the quotes in
echo -n "$(rename -f 's/.*([0-9]{11}_[0-9]{11}).*\.(.*)$/$1.$2/' "$output_dir"*".$ext")"
ところで、ここで達成しようとしているものが何であるか理解できません。呼び出す方法はrename
出力を生成しません。
答え2
通常、シェルが解釈されるのを防ぎます。メタ文字
バックスラッシュ()を使用して\
エスケープします。そうすれば予防できます。みんな$
引数のtheは、
rename
前にバックスラッシュを追加することによって拡張されます。
echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*\$)/\$1.\$2/'" "$output_dir"*.$ext`
この特別なケースでは、文字列にs/.*([0-9]...$2/
シェルレベルの置換が必要ないため(質問のポイントはこれを回避する方法です)、すべての'
シェル処理をブロックする単一引用符()で囲むことができます。
echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`
-f
(シェルメタ文字が含まれていないため、引用する必要はありません。)