我正在寻找一个可以使用的替代破折号命令,因为我试图从 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 shell 中不起作用,因为<()
命令替换格式不可移植,并且当从 python 脚本调用 shell 时,几乎可以肯定启动的/bin/sh
不是 bash(例如dash
在许多 Debian 上)基于系统)或bash
POSIX 模式,或其他一些基本的 POSIX shell。无论如何,这都不是一种非常安全的方法,因为它会受到以下问题的影响:问题解析中固有的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 中本地完成所有这些操作,而不是调用外部 shell。没有理由这不能在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 脚本,我确信它可以得到显着改进,但它应该让您了解可能发生的事情。