文字列または文字列のセットがまだ含まれていないファイルの名前を変更して、その文字列を含めるコマンドラインツールはありますか?
したがって、特定のフォルダ内のすべてのファイルには、「高優先度」の名前にhigh
が含まれている必要がありますが、そうでないものもあります。すべてのファイルに追加するのではなく、ファイルの名前にhigh
が含まれているかどうかを最初に確認し、含まれていない場合は、名前の先頭に追加するにはどうすればよいですか?
bash
を使用している場合、high
Shellオプションが設定されていれば、パターン!(*high*)
は文字列extglob
を含まない現在のディレクトリ内のすべての名前と一致します。
$ shopt -s extglob
$ ls
1 2 3 4-high
$ ls -d -- !(*high*)
1 2 3
次に、このパターンに一致する名前をループして、一致する各名前を変更します。
shopt -s extglob nullglob
for name in !(*high*); do
[[ ! -f $name ]] && continue
mv -- "$name" "high-$name"
done
ここで起こっていることは、ループの前にextglob
とnullglob
(パターンが一致しない場合、グロブパターンをそのまま保持するのではなく非表示にする)を設定することです。非表示の名前の名前も変更する場合は、dotglob
を有効にすることもできます。
次に、ループは通常のファイルを参照しない名前(たとえば、ディレクトリ名など)をスキップし、名前の先頭にmv
を付けて文字列high-
を挿入します。
mv
コマンドの--
は、ダッシュで始まるファイル名を誤ってオプションのセットとして解釈しないようにするためのものです。
これを一連のテストファイルで実行します。
$ ls
1 2 3 4-high
上から直接シェルにコードを貼り付けるだけです。
$ shopt -s extglob nullglob
$
$ for name in !(*high*); do
> [[ ! -f $name ]] && continue
>
> mv -- "$name" "high-$name"
> done
$ ls
4-high high-1 high-2 high-3
Perlのrename
ユーティリティを次のように使用することもできます。
shopt -s extglob
rename -v 'if (-f) { s/^/high-/ }' -- !(*high*)
これにより、この回答の最初のバリエーションのループの-f
テストがPerlに移動しますが、同じファイル名グロビングパターンを使用して、名前を変更するファイルを選択します。 -f
により、名前の変更は通常のファイルにのみ影響します(ディレクトリなどは影響しません)。
シェルの拡張グロブパターンに依存しないバリエーションは、
rename -v 'if (-f && !/high/) { s/^/high-/ }' -- *
これは、名前にhigh
呼び出し内に文字列rename
がすでに含まれているかどうかのテストを実行し、含まれている場合はファイルの名前変更をスキップします。 *
globは、現在のディレクトリ内のすべてのファイルを選択します(非表示のファイルを除く)。
GNU Parallelがある場合:
parallel mv {} '{= /high/ or $_="high$_" =}' ::: *
zsh
の場合:
autoload zmv # best in ~/.zshrc
zmv '^*high*' 'high-$f'
大文字と小文字を区別しないマッチングの場合:
zmv '^*(#i)high*' 'high-$f'