批量重命名txt文件以匹配文件夹,全部在同一目录中?

批量重命名txt文件以匹配文件夹,全部在同一目录中?

在 ~/Desktop/a/ 中,我有文件夹(名称中有空格)和 txt 文件,格式如下:

100 description of project A
100_notes.txt
200 description of project B
200_notes.txt

我想要什么:

100 description of project A
100 description of project A.txt
200 description of project B
200 description of project B.txt

这是到目前为止的脚本:

#!/bin/bash
cd ~/Desktop/a/
for i in *; do
  mv "$i/${f%.txt}" "$i.txt";
done

我正在尝试使用测试文件,它会将文件夹重命名为具有 .txt 扩展名,这不是我想要的。

答案1

#!/bin/sh

for notes in ./???_notes.txt
do
    if [ ! -f "$notes" ]; then
        continue
    fi

    num=${notes%_notes.txt}

    set -- "$num "*/
    if [ "$#" -gt 1 ]; then
        echo 'More than one directory found:' >&2
        printf '\t%s\n' "$@" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    elif [ ! -d "$1" ]; then
        printf 'No directory matching "%s" found\n' "$num */" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    fi

    printf 'Would rename "%s" into "%s"\n' "$notes" "${1%/}.txt"
    # mv -i "$notes" "${1%/}.txt"
done

该脚本将迭代NNN_notes.txt当前目录中的所有文件。对于每个文件,提取数字NNN(可以是任何三个字母的字符串)并用于检测任何目录调用NNN后跟一个空格和任意字符串。

如果找到单个目录,则相应地重命名该文件(为了安全起见,实际重命名被注释掉)。如果找到多个目录或未找到目录,则会显示一条消息指出这一点。

参数替换会从 值的末尾${variable%string}删除字符串。该命令在此脚本中使用时,会将位置参数 、等设置为与给定文件名通配模式匹配的内容(在此脚本中,我们希望该模式与一个目录完全匹配)。该值是此类位置参数的数量。string$variableset$1$2$3$#

按照我编写此脚本的方式,它可以由bash和执行/bin/sh。它不使用任何“bashisms”。

仅Abash版本:

#!/bin/bash

shopt -s nullglob

for notes in ./???_notes.txt
do
    num=${notes%_notes.txt}

    dirs=( "$num "*/ )
    if [ "${#dirs[@]}" -gt 1 ]; then
        echo 'More than one directory found:' >&2
        printf '\t%s\n' "${dirs[@]}" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    elif [ "${#dirs[@]}" -eq 0 ]; then
        printf 'No directory matching "%s" found\n' "$num */" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    fi

    printf 'Would rename "%s" into "%s"\n' "$notes" "${dirs[0]%/}.txt"
    # mv -i "$notes" "${dirs[0]%/}.txt"
done

这里最大的区别是我们使用命名数组dirs来保存模式的可能扩展"$num "*/,并且我们使用nullglobshell 选项将不匹配的文件名模式扩展为空。

相关内容