Localizar e substituir cadeia de caracteres em nomes de arquivos

1

Eu tenho milhares de arquivos sem extensões específicas. O que eu preciso fazer é procurar por uma picada no nome do arquivo e substituí-la por outra string e procurar mais pela segunda string e substituí-la por qualquer outra string e assim por diante. Por exemplo: tenho várias cadeias para substituir por outras cadeias múltiplas. Pode ser assim:

  • "abc" no nome do arquivo substituído por "def" *** A string "abc" pode estar em muitos arquivos
  • "jkl" no nome do arquivo substituído por "srt" *** A string "jkl" pode estar em muitos arquivos
  • "pqr" no nome do arquivo substituído por "xyz" *** A string "pqr" pode estar em muitos arquivos

No momento, estou usando a macro do Excel para obter os nomes dos arquivos no Excel e, em seguida, preservar os nomes originais em uma coluna e substituir o desejado no conteúdo copiado em outra coluna. então eu crio um arquivo de lote para o mesmo. Como:

rename Path\OriginalName1 NewName1
rename Path\OriginalName2 NewName2

O problema com o procedimento acima é que leva muito tempo, pois os arquivos são muitos. E como eu estou usando o Excel 2003, há limitação no número de linhas também. Eu preciso de um script em lote como:

replacestr  abc with def
replacestr  pqr with xyz

em um único diretório. Será melhor fazer em script unix?

    
por shekhar 21.11.2012 / 15:31

4 respostas

3

Se você puder usar o Bash, o script a seguir deverá fazer o que você deseja:

#!/bin/bash

(( $# != 2 )) && exit 1

for f in *; do
  newf="${f//$1/$2}"
  if [[ $f != $newf ]]; then
    mv "$f" "$newf"
  fi
done

Ele tenta substituir o nome do arquivo pela nova string, se o nome do arquivo resultante não corresponder ao original, ele renomeia o arquivo para o nome do arquivo resultante.

Uso, se salvo como replacestr e determinado modo a ser executado:

$ ./replacestr abc def

Ele tentará renomear todos. Você pode usar [[ ! -f $f ]] para pular o não-arquivo. Você também pode envolvê-lo na função e obtê-lo do seu ~/.bashrc se precisar disso com muita frequência.

    
por 21.11.2012 / 16:38
1

Qualquer script que você usa pode ser potencialmente perigoso, mas isso funcionou para mim em uma escala limitada (acabei de tocar cerca de 15 arquivos e fiz um csv rápido de abc, 123 \ n def, 456 - etc.

Com isso fora do caminho, eu faria um backup rápido, testaria isso em alguns e depois o lançaria.

Pressupostos :
-O excel é exportado para CSV com o formato oldname,newname em cada linha
-Você está em uma concha bash.
-Todos em um diretório
-São todos os arquivos (você pode alterar o script para dirs alterando -type f para -type d

#!/bin/bash
inputfile=${1}
while read line
do
    IFS=',' read -a names <<< "${line}"
    for file in 'find . -maxdepth 1 -type f -name "*${names[0]}*"'; do
        rename "s/${names[0]}/${names[1]}/" *
    done
done < ${inputfile}

Isso funcionará no diretório atual ( find . ) e funcionará apenas no nível 1 ( -maxdepth 1 ), itens facilmente alterados. Espero que pelo menos você fique no caminho certo.

O importante é que isso mantém o resto do nome do arquivo e somente substitui a string de entrada pela saída. Portanto, o arquivo 123abc123.null com entrada de abc,999 resultaria em 123999123.null .

Basta torná-lo executável com chmod +x nameofmyscript.sh e executá-lo com ./nameofmyscript.sh input/file/location.csv

    
por 21.11.2012 / 16:24
0

Aqui está um howto . Existem muitas receitas e até mesmo um roteiro. Espero que você encontre o que está procurando.

Na verdade, você deve estudar expressões regulares para entender melhor o assunto.

    
por 21.11.2012 / 15:53
0

Em um arquivo em lotes do Windows:

@echo off
setlocal enabledelayedexpansion
set needle=%~1
set replace=%~2
pushd %3
for %%i in (*.*) do (
    echo %%i|findstr "%needle%"> nul && (set match=%%i&move /-Y "%%i" "!match:%needle%=%replace%!")
)
popd

Exemplo de sintaxe: batchrename.bat "abc" "def" ".\bigfolder"

Ele funciona alterando o diretório atual se um for especificado, passando-o usando for (use o sinalizador / R para incluir subdiretórios). Em seguida, ele canaliza o nome do arquivo para um comando findstr, que irá compará-lo com uma string de agulha. Se uma correspondência for encontrada, a linha será impressa, mas suprimida por > nul . Se nenhuma correspondência for encontrada, o nível de erro será definido como um, após o qual && impedirá a execução do restante do comando.

A variável %%i é então copiada em %match% , porque a forma do iterador não suporta a substituição de substring. Em seguida, o nome do arquivo é renomeado pelo comando move usando uma string de destino alterada !match:%needle%=%replace%! .

Observe que erros de digitação ou erros podem atrapalhar seus nomes de arquivos. Use com cuidado.

    
por 21.11.2012 / 16:32