Remove o espaço em branco inicial de arquivos, pastas e suas subpastas

3

Eu criei isso, mas infelizmente ele não afeta nenhum arquivo / pasta em subpastas.

find . -exec rename "s/^\s+//" {} \;

Estrutura de pastas:

foo
|-- \ bar
'-- \ foo1
    |-- \ bar1
    '-- \ foo2
        '-- \ bar2
    
por Sascha 12.05.2016 / 11:44

3 respostas

2

A renomeação precisa ser feita de baixo para cima

O problema é que você precisa renomear os diretórios de baixo para cima . Senão o comando tentará renomear arquivos & diretórios que estão dentro de pastas já movidas (renomeadas) e, portanto, não podem mais encontrá-las.

Aqui é onde python os.walk() pode ser usado, em combinação com topdown=False

Em um pequeno script:

#!/usr/bin/env python3
import os
import shutil
import sys

for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        if f.startswith(" "):
            shutil.move(root+"/"+f, root+"/"+f.strip())
    for dr in dirs:
        if dr.startswith(" "):
            shutil.move(root+"/"+dr, root+"/"+dr.strip())

Para usar

  • Copie o script em um arquivo vazio, salve-o como no_space.py
  • Execute-o pelo comando:

    python3 /path/to/no_space.py /path/to/directory/to/rename
    
por Jacob Vlijm 12.05.2016 / 15:17
2

Como observado em outras respostas, a questão principal é que ^ ancora o início do caminho , em vez do início do nome do arquivo. Há várias maneiras de contornar isso com find e rename : provavelmente, o mais seguro seria usar -execdir no lugar de -exec para que todos os componentes do caminho sejam reduzidos para ./ e, em seguida, substitua o padrão \./\s+

Além disso, se você estiver renomeando os diretórios possivelmente incluindo ancestrais de outros arquivos / diretórios que serão renomeados , então você deve fazer uma travessia em profundidade.

Colocando tudo junto,

find . -depth -name ' *' -execdir rename -vn -- 's#\./\s+##' {} +

ou (funcionalmente equivalente, mas um pouco mais fácil de ver o que está acontecendo) usando um "lookbehind" de comprimento zero para o separador de caminho

$ find . -depth -name ' *' -execdir rename -vn -- 's#(?<=\./)\s+##' {} +
./ bar2 renamed as ./bar2
./ foo2 renamed as ./foo2
./ bar1 renamed as ./bar1
./ foo1 renamed as ./foo1
./ bar renamed as ./bar

[NOTA: remova o -n assim que tiver certeza de que faz o que quiser]

    
por steeldriver 12.05.2016 / 13:34
1

Eu acho que o problema é com o formato de saída de find, que inclui o caminho completo. Então, para o bar2, você terá

./ foo1/ foo2 /bar2

essa renomeação não entenderá corretamente.

Uma solução é usar um script para fazer cada pasta de forma recursiva assim:

#!/bin/bash
# if argument given consider it is the directory to parse
if [ -n "$1" ]; then
    cd "$1"
fi
# rename all files in current folder
find . -maxdepth 1 -printf '%f
./ foo1/ foo2 /bar2
' | xargs -0r -n 1 rename -nono 's/^\s+//' # No, repeat for all subfolders with current script (we are in the subfolder) find . -maxdepth 1 -type d -not -name '.' -print0 | xargs -0r -n 1 "$(readlink -f $0)"
    
por Camilio 12.05.2016 / 13:20