Pythonでコードを実行しようとしていますが、サブフォルダに100個のファイルがあるため、使用できる代替ダッシュコマンドを探しています。ファイルを10個のフォルダにグループ化しようとしていますが、Pythonスクリプトは必要ありません。邪魔になろう。
私が試しているコマンドは "<()" のためダッシュでは機能せず、代替を探しています。
パスワード:
i=0;while read l;do mkdir folder$i;mv $l folder$((i++));done< <(ls|xargs -n10)
間違い:
Syntax error: redirection unexpected
答え1
このコードはbashでは機能しますが、POSIXシェルでは機能しません。<()
これは、コマンドの代替形式は移植可能ではなく、シェルがPythonスクリプトから呼び出されたときに実行/bin/sh
されるbash(たとえばdash
、多くのDebianベースのシステム)またはbash
POSIXモードではないことがほとんど確実であるためです。または他のデフォルトPOSIXシェル。これは、次の問題により非常に安全なアプローチではありません。質問解析に固有のものですls
。
別のアプローチは次のとおりです。
k=0
for file in *; do
[ "$k" = 10 ] && k=0
mkdir -p folder"$k"
mv -- "$file" "folder$k"
k=$((k+1))
done
mkdir -p
すべての実装がこのオプションをサポートしているわけではないので、移植性がないことに注意してください-p
(ディレクトリがすでに存在していると文句を言わないでください)mkdir
。これが問題の場合は、ターゲットディレクトリが存在するかどうかをテストするコードを追加したり、エラーメッセージを無視したりできます。
つまり、Pythonスクリプトを作成する場合は、外部シェルを呼び出すのではなく、Pythonでローカルでこれをすべて行う必要があります。 Pythonでこれを行うことができない理由はありません。別のディレクトリで発生する必要があると述べましたが、まったく問題にはなりません。 Pythonコードをもっと注意深く見て、Pythonで実装することをお勧めします。
たとえば、同じことを行うPythonスクリプトは次のようになります。
#!/usr/bin/env python3
import os
import shutil
import sys
# read the first argument into source_dir
source_dir = sys.argv[1]
dir_counter = 0
file_counter = 0
target_dir = os.path.join(source_dir, "folder")
for file_name in os.listdir(source_dir):
# If this is a file
if os.path.isfile(file_name):
file_counter += 1
# If this file number is a multiple of 10,
# change the target dir name
if file_counter % 10 == 0:
dir_counter += 1
target_dir = os.path.join(source_dir, "folder" + str(dir_counter))
# Create the dir if it doesn't exist
if not os.path.exists(target_dir):
os.mkdir(target_dir)
try:
shutil.move(file_name, target_dir)
except Exception as error_message:
print("Failed to move %s to %s with error %s" %
(file_name, target_dir, error_message))
次に、ソースディレクトリを引数として使用してスクリプトを実行します。
foo.py /path/to/source/directory
これは特にエレガントなPythonスクリプトではなく、かなり改善することができると確信していますが、今後何が起こるかについてのアイデアを提供します。