执行以下任务的脚本不是更改目录:

执行以下任务的脚本不是更改目录:

我有一个 shell / bash 脚本,它将重命名文件夹中的某些文件。我在几个文件夹中都有相同的文件。我希望有一个文件可以执行所有文件夹的操作。

#!/bin/bash
for name in *.png; do
    # remove everything after the last '-' including the dash
    # and add the '.png' extension back
    newname="${name%-*}.png"
    mv "$name" "$newname"
done

答案1

如果您只想处理目录顶层(即:深度一层)的文件,那么您不需要递归。

这两个示例都将目录列表作为参数,并仅重命名符合更独特模式的目录中的文件:(*-*.png以避免命令可能失败mv)。

执行以下任务的脚本不是更改目录:

在第一个脚本中,在for循环内部,变量name除了包含基本文件名之外,还包含文件的目录路径。

#!/bin/sh
for dir in "$@"
do
    for name in "$dir"/*-*.png
    do
        mv "$name" "${name%-*}.png"
    done
done

脚本更改目录:

在第二个脚本中,在for循环内部,name变量仅包含文件名,因为当前目录已被临时更改为脚本参数。

括号(), 之间的代码在子壳环境意味着更改当前目录以及设置的变量对于外壳脚本来说是不可见的,从而无需“改回”原始目录。

#!/bin/sh
for dir in "$@"
do
    (
        if cd "$dir"
        then
            for name in ./*-*.png
            do
                mv "$name" "${name%-*}.png"
            done
        fi
    )
done

关于这两个脚本的说明:

扩展"$@"为脚本的命令行参数。如果没有参数,脚本将默默地不执行任何操作。

目录名称参数可以是任何绝对路径()/path/to/dirx或相对路径(,,,,,dirx等)。path/to/diry...../x/d1

mv如果cd给定目录不存在,或者目录中没有文件,则消息将通过或打印到标准错误流 (stderr) 上*-*.png。脚本将继续处理后续目录。

这些脚本的第一行可以用#!/bin/sh代替,bash因为此脚本不使用任何功能,因此可以使用bash更便携、更符合 posix 且可能更快的功能。很少有脚本需要shell 的额外功能。出于这些和其他原因,通常不建议用于脚本。shbash#!/bin/bash

答案2

这对我有用

 for dir in *; do if cd $dir; then  for filename in *; do mv $filename "$filename.pdf"; done; cd ..; fi; done

相关内容