如何使用具有两个相互依赖的变量的 For 循环?

如何使用具有两个相互依赖的变量的 For 循环?

我有一个包含 100 个 .mp4 文件的主目录。我还有一组子目录dir_1, dir_2, dir_3,最多 100 个。我想要做的是循环主目录并将 .mp4 文件分发到所有子文件夹,每个子文件夹只有一个。然后,应该有两个循环或一个有两个变量的循环,无论哪一个都是可能的。这大约是我试图通过一行代码实现的目标。

for file in *.mp4 & x in {1..100}; do mv $file dir_$x; done

答案1

set -- *.mp4

for dir in dir_*/; do
    mv -- "$1" "$dir"
    shift
done

首先使用将所有 MP4 文件的名称分配给位置参数列表set。然后它迭代与模式匹配的目录dir_*/。对于每个目录,它将第一个 MP4 文件从位置参数列表移动到该目录中,然后将该 MP4 文件移出列表。

上面的代码中没有检查来验证目录是否与 MP4 文件一样多。你想要吗,你可以做

set -- *.mp4

for dir in dir_*/; do
    if [ "$#" -eq 0 ]; then
        echo 'Ran out of MP4 files' >&2
        exit 1
    fi
    mv -- "$1" "$dir"
done

if [ "$#" -ne 0 ]; then
    echo 'Too many MP4 files' >&2
    exit 1
fi

这段代码可以在任何sh类似 POSIX shell 中工作。

答案2

使用一个循环,使用算术表达式递增计数器。

x=1
for file in *.mp4 ; do
    mv -- "$file" dir_$x/
    ((++x))
done

将文件名用双引号引起来,因为 mp4 的名称中可以包含空格。如果文件名以破折号开头--,则在前面使用"$file"可避免将文件名解释为一组选项。

答案3

另一种攻击主义:

#!/bin/bash

mp4=( ./*.mp4 )
for i in "${!mp4[@]}"
do
    mv "${mp4[i]}" "dir_$i/"
done

我不会在你的情况下使用它,但看到不同的方法总是很有趣。

相关内容