переименование папок с использованием .txt-файла

7

Я работаю в своем терминале, используя bash, чтобы переименовать папки:

1
2
3
4
5

Я хотел бы переименовать их в соответствии с файлом a.txt:

a 2
c 3
d 5
e 1
b 4

Порядок в файле .txt полностью случайный. Я надеюсь найти способ, которым я могу переименовать папку, чтобы они стали:

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

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

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

    
задан Ditte 31.05.2016 в 08:11
источник

4 ответа

4

Предполагая, что имена в списке не включают пробелы , кроме между именами, сценарий ниже будет переименовывать папки из текстового файла <ет> рекурсивно . Он прочитает строки файла, разделит их на два (новое имя, старое имя), переименуйте папки, имена которых обозначены строкой second в строке, в first строка в строке.

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

#!/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. Скопируйте сценарий в пустой файл (в редакторе plain text ), сохраните его как rename.py
  2. В главном разделе скрипта задайте реальные пути к текстовому файлу и директории
  3. запустите его командой (в терминале):

    python /path/to/rename.py
    

Объяснение

Сценарий:

  • создает список имен pairs : newname / oldname
  • используя python os.walk() , он рекурсивно просматривает ваши каталоги, снизу вверх.
  • Если имя папки совпадает с вторым элементом пары имени, она переименовывает папку в имя.
  • Если имя папки отсутствует в списке, оно будет не тронуто.
ответ дан Jacob Vlijm 31.05.2016 в 08:56
источник
6

Вы можете использовать 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 ?...
    
ответ дан muru 31.05.2016 в 08:27
источник
2

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

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

Попробуйте это, если имена не содержат ни \n , ни space chars:

awk '{printf("%s
$ 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%pr_e%%s%pr_e%",$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
%s%pr_e%",$2,$1)}' a.txt | xargs -0 -L 2 mv

awk используется для изменения порядка имен в строках, считанных из файла a.txt . xargs используется для разделения имен при печати на стандартный вывод.

-0 читает стандартный ввод:

  • -L 2 mv : mv используется как разделитель для элементов, считанных со стандартного ввода
  • Команда %co_de% : %co_de% вызывается с двумя параметрами за раз.

Тест:

%pr_e%     
ответ дан Jay jargot 31.05.2016 в 09:33
источник
2

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

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

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

ответ дан terdon 31.05.2016 в 11:24
источник

Ознакомьтесь с другими вопросами по меткам