переименование папок с использованием файла .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

Есть ли способ сделать это?

Большое спасибо!

7
задан 31 May 2016 в 21:19

4 ответа

Брать имена в списке не включает пробелы, кроме между именами, сценарий ниже переименует папки из текстового файла рекурсивно. Это считает строки файла, разделит их на два (новое имя, старое название), переименовать происходящие папки, которые называет вторая строка в строке в первую строку в строке.

Это сделает это, как упомянуто рекурсивно, от нижней части до вершины в дереве каталогов. Это предотвращает проблемы в сценарии, пытаясь уже переименовать папки в возможно переименованных родительских папках.

#!/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
    

Объяснение

Сценарий:

  • создает список имени - пары: newname/oldname
  • использование Python os.walk(), это просматривает Ваши каталоги рекурсивно от нижней части до вершины.
  • Если имя папки соответствует второму объекту пары имени, это переименовывает папку в имя.
  • Если имя папки не будет перечислено, то это будет нетронутым.
4
ответ дан 31 May 2016 в 21:19

В простом случае Вы показываете выше, где каждая строка имеет два "слова", целевой каталог и новое имя, и где ни один не может содержать пробел, можно просто сделать:

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

, Который считает каждую строку в file, присваивают первую строку (до первого пробела) к $from и остальная часть строки к $to и затем работают mv на каждом из них.

2
ответ дан 31 May 2016 в 21:19

Существует одна запись на строку в a.txt файл, таким образом, перечисленные имена не содержат \n (новая строка) символ, правильно?

строка А содержит 2 имени, разделенные с пространство символ, таким образом, имена не содержат пространство символ, правильно? (или другая возможность состояла бы в том, чтобы использовать фиксированную длину для перечисленных имен).

Дают попытку этому, если имена не содержат ни \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 mv: mv команда вызывается с 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
2
ответ дан 31 May 2016 в 21:19

Вы могли использовать 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 ?...
6
ответ дан 31 May 2016 в 21:19

Другие вопросы по тегам:

Похожие вопросы: