Bash 为每个 x 文件创建子文件夹并将文件移动到那里

Bash 为每个 x 文件创建子文件夹并将文件移动到那里

我正在寻找一个可以使用的替代破折号命令,因为我试图从 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 上)基于系统)或bashPOSIX 模式,或其他一些基本的 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 脚本,我确信它可以得到显着改进,但它应该让您了解可能发生的事情。

相关内容