使用 .txt 文件重命名文件夹

使用 .txt 文件重命名文件夹

我正在终端中使用 bash 尝试重命名文件夹:

1
2
3
4
5

我想根据.txt文件重命名它们:

a 2
c 3
d 5
e 1
b 4

.txt 文件中的顺序完全是随机的。我希望找到一种方法来重命名文件夹,使它们变成:

1 > e
2 > a
3 > c
4 > b
5 > d

有什么办法可以做到这一点?

多谢!

答案1

您可以xargs使用mv

xargs -r -a /path/to/file.txt -L1 mv

(假设您位于文件所在的目录中)。

xargs将输入转换为命令的参数。

  • -a foo读取输入foo
  • -L1每次命令调用时只使用一行输入。
  • -r避免在行为空时运行命令

例如,使用echo mv而不是mv显示正在运行的命令:

$ xargs -r -a foo.txt -L1 echo mv
mv a 2
mv c 3
mv d 5
mv e 1
mv b 4

您还可以使用该选项在运行命令之前-p进行确认:xargs

$ xargs -r -p -a foo.txt -L1 mv
mv a 2 ?...n
mv c 3 ?...n
mv d 5 ?...y
mv e 1 ?...mv: cannot stat ‘d’: No such file or directory
n
mv b 4 ?...

答案2

假设列表中的名称不包含空格, 以外之间名称,下面的脚本将从文本文件重命名文件夹递归地它将读取文件的行,将它们拆分为两个(新名称,旧名称),重命名出现的文件夹,这些文件夹由第二字符串在行中,进入第一的行中的字符串。

如上所述,它将执行此操作递归地,在目录树中从下到上。这可以防止脚本出现问题,尝试重命名可能已重命名父文件夹中的文件夹。

#!/usr/bin/env python
import os
import shutil

# -- set the (absolute) path to the targeted folder below
dr = "/home/jacob/Bureaublad/testfolder"
# -- set the path to the textfiles below
ren = "/home/jacob/Bureaublad/testfolder/renfile.txt"

renlist = [cpl for cpl in [l.split() for l in open(ren).readlines()] if cpl]
currnames = [r[1] for r in renlist]

for root, dirs, files in os.walk(dr, topdown = False):
    for dr in dirs:
        try:
            # look up the name, pass if not in the list
            i = currnames.index(dr)
        except ValueError:
            pass
        else:
            newname = renlist[i][0]
            shutil.move(root+"/"+dr, root+"/"+newname)

如何使用

  1. 将脚本复制到一个空文件中(在纯文本编辑器),另存为rename.py
  2. 在脚本的头部,设置文本文件和目录的实际路径
  3. 通过以下命令运行它(在终端中):

    python /path/to/rename.py
    

解释

剧本:

  • 创建一份名单夫妇:新名称/旧名称
  • 使用 python 的os.walk(),它会从下到上递归地查看您的目录。
  • 如果文件夹的名称与名称对中的第二项匹配,它会将文件夹重命名为第一个名称。
  • 如果未列出该文件夹的名称,则它将保持不变。

答案3

文件中每行有一个条目a.txt,因此列出的名称不包含\n(换行)字符,对吗?

一行包含 2 个名字,用空间char,因此名称不包含空间char,对吧?(或者另一种可能性是对列出的名称使用固定长度)。

如果名称不包含字符,请尝试以下\n操作space

awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv

awk用于反转从a.txt文件读取的行中名称的顺序。\0用于在将名称打印到标准输出时分隔名称。

xargs读取标准输入:

  • -0:\0用作从标准输入读取的元素的分隔符
  • -L 2 mvmv命令每次调用时都带有 2 个参数。

考试:

$ ls -al
total 40
drwxrwxr-x  7 stacko stacko  4096 May 31 11:25 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 1
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 2
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 3
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 4
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 5
-rw-rw-r--  1 stacko stacko    20 May 31 11:24 a.txt
$ cat a.txt
a 2
c 3
d 5
e 1
b 4
$ awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv -v
'2' -> 'a'
'3' -> 'c'
'5' -> 'd'
'1' -> 'e'
'4' -> 'b'
$ ls -al
total 40
drwxrwxr-x  7 stacko stacko  4096 May 31 11:26 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 a
-rw-rw-r--  1 stacko stacko    20 May 31 11:24 a.txt
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 b
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 c
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 d
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 e

答案4

在上面显示的简单情况下,每行有两个“单词”,即目标目录和新名称,并且都不包含任何空格,您可以简单地执行以下操作:

while read -r from to; do mv "$from" "$to"; done < file 

这将读取每一行,将file第一个字符串(直到第一个空格)分配给并将$from该行的其余部分分配给$to,然后mv在每一行上运行。

相关内容