renomear pastas usando um arquivo .txt

7

Estou trabalhando no meu terminal usando bash tentando renomear as pastas:

1
2
3
4
5

Gostaria de renomeá-los de acordo com o arquivo a.txt:

a 2
c 3
d 5
e 1
b 4

A ordem no arquivo .txt é completamente aleatória. Espero encontrar uma maneira de renomear a pasta para que ela se torne:

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

Existe alguma maneira de fazer isso?

Muito obrigado!

    
por Ditte 31.05.2016 / 10:11

4 respostas

4

Supondo que os nomes na lista não incluam espaços , além de entre os nomes, o script abaixo renomeará as pastas de um arquivo de texto recursivamente . Ele irá ler as linhas do arquivo, dividi-las em duas (nome novo, nome antigo), renomear as pastas que são nomeadas pela string segundo na linha, na primeira string na linha.

Ele fará isso, como mencionado recursivamente , de baixo para cima na árvore de diretórios. Isso evita problemas no script, tentando renomear pastas em pastas pai possivelmente já renomeadas.

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

Como usar

  1. Copie o script em um arquivo vazio (em um editor texto simples ), salve-o como rename.py
  2. Na seção head do script, defina os caminhos reais para o arquivo de texto e o diretório
  3. execute-o pelo comando (em um terminal):

    python /path/to/rename.py
    

Explicação

O script:

  • cria uma lista de nomes- casais : newname / oldname
  • usando o os.walk() do python, ele analisa seus diretórios de forma recursiva, de baixo para cima.
  • Se o nome da pasta corresponder ao segundo item de um casal de nomes, ele renomeia a pasta para o primeiro nome.
  • Se o nome da pasta não estiver listado, ele não será alterado.
por Jacob Vlijm 31.05.2016 / 10:56
6

Você pode usar xargs com mv :

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

(supondo que você esteja no diretório em que os arquivos estão localizados).

xargs converte a entrada em argumentos para um comando.

  • -a foo para ler a entrada de foo .
  • -L1 para usar exatamente uma linha de entrada por chamada de comando.
  • -r para evitar a execução do comando se a linha estiver vazia

Por exemplo, usando echo mv em vez de mv para mostrar os comandos sendo executados:

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

Você também pode usar a opção -p para tornar xargs confirm antes de executar o comando:

$ 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 ?...
    
por muru 31.05.2016 / 10:27
2

Existe uma entrada por linha no arquivo a.txt , então os nomes listados não contêm \n (nova linha) char, certo?

Uma linha contém 2 nomes separados por um espaço char, então os nomes não contêm espaço char, certo? (ou outra possibilidade seria usar tamanho fixo para os nomes listados).

Tente fazer isso se os nomes não contiverem \n nor 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
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%pre%%s%pre%",$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%pre%",$2,$1)}' a.txt | xargs -0 -L 2 mv
%s%pre%",$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%pre%",$2,$1)}' a.txt | xargs -0 -L 2 mv

awk é usado para reverter a ordem dos nomes nas linhas lidas do arquivo a.txt . xargs é usado para separar os nomes quando eles são impressos na saída padrão.

-0 lê a entrada padrão:

  • -L 2 mv : mv é usado como separador para os elementos lidos da entrada padrão
  • O comando %code% : %code% é chamado com 2 parâmetros por vez.

O teste:

%pre%     
por Jay jargot 31.05.2016 / 11:33
2

No caso simples que você mostra acima, onde cada linha tem duas "palavras", o diretório de destino e o novo nome, e onde nenhum deles pode conter nenhum espaço em branco, você pode simplesmente fazer:

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

Isso lerá cada linha em file e atribuirá a primeira cadeia (até o primeiro espaço em branco) a $from e o restante da linha a $to e, em seguida, a executar mv em cada uma delas.

    
por terdon 31.05.2016 / 13:24