
mv
並べ替える必要があるファイルが100万以上あるフォルダがありますが、このメッセージが引き続き出力されるため、何もできません。
-bash: /bin/mv: Argument list too long
拡張子なしでファイルを移動するには、次のコマンドを使用します。
mv -- !(*.jpg|*.png|*.bmp) targetdir/
答え1
xargs
作業のためのツールです。それ、またはfind
そして-exec … {} +
。これらのツールはコマンドを複数回実行して、一度にできるだけ多くのパラメータを渡します。
どちらの方法も、可変引数リストが最後にあるときに実行する方が簡単ですが、ここではそうではありません。最後の引数がmv
ターゲットです。 GNUユーティリティ(つまり、組み込まれていないLinuxまたはCygwin)の場合、-t
このオプションはターゲットをmv
最初に渡すのに役立ちます。
ファイル名にスペースや\"'
スペースが含まれ-
ておらず、1で始まらない場合は、ファイル名を入力として指定するだけです(xargs
コマンドはbashに組み込まれているため、コマンドラインの長さ制限は適用されecho
ません)。ワイルドカード構文を有効にします。!: event not found
shopt -s extglob
echo !(*.jpg|*.png|*.bmp) | xargs mv -t targetdir --
-0
このオプションを使用すると、デフォルトのxargs
引用形式の代わりにnullで区切られた入力を使用できます。
printf '%s\0' !(*.jpg|*.png|*.bmp) | xargs -0 mv -t targetdir --
またはを使用できますfind
。サブディレクトリが繰り返されるのを防ぐには、を使用します-type d -prune
。リストされたイメージファイルに対して指定された操作がないため、他のファイルのみが移動されます。
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec mv -t targetdir/ {} +
(ここにはシェルワイルドカード方法とは異なり、ドットファイルが含まれます。)
GNU ユーティリティがない場合は、中間シェルを使用して引数を正しい順序で取得できます。この方法はすべてのPOSIXシステムで動作します。
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec sh -c 'mv "$@" "$0"' targetdir/ {} +
zshではロードできますmv
組み込み:
setopt extended_glob
zmodload zsh/files
mv -- ^*.(jpg|png|bmp) targetdir/
mv
または let と他の名前が外部コマンドを参照し続けたい場合:
setopt extended_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- ^*.(jpg|png|bmp) targetdir/
またはkshスタイルのglobを使用してください。
setopt ksh_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- !(*.jpg|*.png|*.bmp) targetdir/
またはGNUを使用mv
してzargs
:
autoload -U zargs
setopt extended_glob
zargs -- ./^*.(jpg|png|bmp) -- mv -t targetdir/ --
¹一部のxargs
実装では、ファイル名は現在のロケールの有効なテキストでなければなりません。一部の人は、入力の終わりを示す_
ためにファイル名を指定することを検討するかもしれません-E ''
。
答え2
Linuxカーネルを使用すれば十分であれば簡単にできます。
ulimit -S -s unlimited
これは、Linuxカーネルにスタックサイズに応じてパラメータ制限を変更したパッチが約10年前に含まれていたためです。https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b6a2fea39318e43fee84fa7b0b90d68bed92d2ba
無限のスタックスペースを望まない場合は、次のように言えます。
ulimit -S -s 100000
スタックを100MBに制限します。スタックスペースを通常のスタック使用量(通常8 MB)に使用するコマンドラインサイズを加算した値に設定する必要があります。
以下で実際の制限を確認できます。
getconf ARG_MAX
これにより、最大コマンドライン長がバイト単位で出力されます。たとえば、Ubuntuのデフォルト値は2097152
約2MBです。無限スタックで実行すると得られるサイズは4611686018427387903
正確に2^62または約46000TBです。コマンドラインが次を超える場合それ、問題を直接解決できることを願っています。
asをすぐに使用すると、sudo
実際の実行前にスタックサイズがリセットされるため、問題を解決できません。この問題を解決するには、を使用してルートシェルを起動して実行し、最後にルートシェルでコマンドを実行せずにコマンドを実行する必要があります。sudo mv *.dat somewhere/.
ulimit
sudo
mv
sudo -s
ulimit -S -s unlimited
sudo
答え3
時には最も簡単な方法はPythonのような小さなスクリプトを書くことです。
import glob, shutil
for i in glob.glob('*.jpg'):
shutil.move(i, 'new_dir/' + i)
答え4
オペレーティングシステムのパラメータ転送制限は、シェルインタプリタ内で発生する拡張には適用されません。したがってxargs
、orを使用する代わりに、find
単にシェルループを使用して処理を別々のコマンドmv
に分割できます。
for x in *; do case "$x" in *.jpg|*.png|*.bmp) ;; *) mv -- "$x" target ;; esac ; done
これはPOSIXシェルコマンド言語機能とユーティリティのみを使用します。このテキストはインデントし、不要なセミコロンを削除することでより明確になりました。
for x in *; do
case "$x" in
*.jpg|*.png|*.bmp)
;; # nothing
*) # catch-all case
mv -- "$x" target
;;
esac
done