根据文件名的算术条件移动文件

根据文件名的算术条件移动文件

我有一个文件夹,里面有一堆文件,结构如下: image_<N1>_<N2>.png 其中 N1 范围为 0:238002,N2 范围为 0:3。

我只想将 N1 <= 18003 和 N2 == 0 的文件移动到另一个文件夹。有没有快速简便的方法可以做到这一点?

N1 的格式不是固定位数。例如,N1=23 将是image_23_0.png不是 image_000023_0.png

操作系统是 Ubuntu。

答案1

bash可以这样做:

mv image_{0..18003}_0.png target_dir/

N2往常一样0,可以将其用作固定字符串。 {a..b}计算范围从a到的所有选项b。这也适用于字母表,但要小心使用除 26 个字母表以外的其他语言环境。


为了避免由于参数列表太长而导致的错误,请使用xargs

seq 0 18003 | xargs -I{} mv image_'{}'_0.png target_dir/

xargs是一个将输入列表转换为一系列命令的工具,重点是尽可能少地运行命令。简而言之。

这里seq创建了一个从 0 到 18003 的数字序列,该序列通过管道传输(|= 转发)作为的输入xargs-I{}表示用传入的输入替换{}指定的命令以创建一系列命令。

答案2

另一种方法是使用稍长一些的 bash 脚本来执行所有操作,充分利用 bash 的模式匹配和模式提取运算符。如下所示:

# Be sure to set this properly - this will
# fail as written
target=<...some other directory>
# adjust these as needed
N1limit=18003
N2value=0

# read from the output of the ls command,
# one line at a time, respecting spaces, etc.
# Using read's default variable (REPLY)
# saves some quoting and mangling headaches.
while IFS=\  read -r; do
    fileName="${REPLY}"

    # CONSIDER ADDING LOGIC HERE TO CHECK IF fileName
    #   a) refers to a file, not a directory, and
    #   b) matches the desired pattern;
    # IF IT DOESN'T, continue to the next file

    # get everything up to the end of N1
    N1End="${fileName%_*}"
    # get N1 itself
    N1="${N1End#*_}"
    # get everything up to the beginning of N2
    N2Start="${fileName##*_}"
    # get N2 itself
    N2="${N2Start%.*}"
    # do the move IFF N1 is at or below the limit
    # AND N2 is equal to the desired value
    if [[ $n1 -le $N1limit && $N2 -eq $N2value ]]; then
        mv "${fileName}" "${target}"
    fi
done <<<$(ls)

相关内容