Erro ao renomear muitas pastas[RESOLVIDO]

1. Erro ao renomear muitas pastas[RESOLVIDO]

Jean César
dark777

(usa Linux Mint)

Enviado em 13/01/2020 - 13:49h

wiki.anon

Boa tarde galera criei um script para renomear uma grande quantidade de pastas removendo
espaços ifens e algum ponto que tem no nome das pastas colocando underline,
fiz este script baseado em outro que tenho para renomear uma grande quantidaade de imagens,

porem ao fazer o teste no script deu o seguinte erro:

bash$ mkdir "Nova pasta.DRift-Asdf java" "Nova pasta.DRift-Asdf Java"

bash$ bash renamedir
Nova pasta.DRift-Asdf Java/ Nova pasta.DRift-Asdf java/ Nova_pasta_DRift-Asdf_Java/_Nova_pasta_DRift-Asdf_java/

Directory: Nova pasta.DRift-Asdf Java
Nova pasta.DRift-Asdf java/

Renamed: Nova_pasta_DRift-Asdf_Java_Nova_pasta_DRift-Asdf_java/ successfully


Nova pasta.DRift-Asdf Java/ Nova pasta.DRift-Asdf java/ Nova_pasta_DRift-Asdf_Java/_Nova_pasta_DRift-Asdf_java/

Directory: Nova pasta.DRift-Asdf Java
Nova pasta.DRift-Asdf java/

Renamed: Nova_pasta_DRift-Asdf_Java_Nova_pasta_DRift-Asdf_java/ successfully

ele esta pegando o nome das duas pastas e unindo em um nome só tentei resolver isso mas nao consegui alguem poderia me ajudar?

O script é este abaixo:

#!/bin/bash

#Renomeia apenas diretórios
k=1

while [ "${k}" -le "$(ls -d */ | wc -l)" ];
do

DIRECTORY="$(ls -d */)"
NEWNAME="$(echo ${DIRECTORY} | sed 's/^ //g;s/ - /_/g;s/ /_/g;s/ $//g;s/\./_/g;s/__/_/g;')"

echo ${DIRECTORY} ${NEWNAME}

if [ $? -ne 0 ]; then
echo -e "\033[37;1m${k} \033[m<-\033[31;1m nothing done.!!\033[m"
else
echo -e "\033[36;1m\n\tDirectory\033[35;1m: \033[m${DIRECTORY/\//}\033[31;1m\n\n\tRenamed\033[35;1m: \033[33;1m${NEWNAME/\//}\033[m successfully\n\n"
fi

k=$((${k}+1))

done



  


2. Re: Erro ao renomear muitas pastas[AJUDA]

Perfil removido
removido

(usa Nenhuma)

Enviado em 13/01/2020 - 16:44h

Segue sugestão.
#!/bin/bash
# Rename files/dirs to 'snake_case' and remove punctuation chars
# Renomeia arquivos para 'snake_case' e retira sinais de pontuação
# Uso: 1. entre no diretório pai que contém os dirs/arqs alvos
#
# 2. se quiser mover os dirs/arqs para outra pasta:
# $ script.sh /OUTRA/PASTA/DESTINO #use caminho completo!
#
# do contrário, ele moverá os alvos para a mesma pasta (renomeará somente)
#
# Obs: configure o 'glob' do Printf de acordo com sua necessidade!

#se não for especificado diretório de destino como primeiro
#argumento do script, usar o dir atual como destino
TODIR="${1:-.}"

#função de substituição do sed
#substitue todos os chars a seguir por '_'
CHARS='!"#$%&()*+,.:;<=>?@^`{|}~ -'
sedf() { sed "/[_${CHARS}]/!{q100}; {s/[${CHARS}]/_/g}" | sed 's/___*/_/g';}

#se não houver, crie o diretório de destino
mkdir -p "${TODIR}" || exit 1

#criar lista de arqs/dirs alvos.
#DESCRIÇÃO GLOB
#todos os arqs: *
#todos os dirs: */
#arqs que começam com '.': .??* #must have at least 3 chars, ignores . and ..
#dirs que começam com '.': .*/
#todos arqs+dirs mesmo: .??* *
#Obs: para listar arqs somente (não-diretórios), declare um 'if [[ -f ...'
printf '%s\n' */ |
#enquanto lê a lista:
while read X; do
#processa o nome do diretório
if Y="$(sedf <<<"${X}")" #&& [[ -f "${X}" ]]
then
#mv "${X}" "${TODIR%/}/${Y}" #&&
echo -e "${X}\t>>> ${TODIR%/}/${Y}"
fi
done

#https://www.vivaolinux.com.br/topico/Shell-Script/Erro-ao-renomear-muitas-pastasAJUDA/
#https://www.gnu.org/software/grep/manual/html_node/Character-Classes-and-Bracket-Expressions.html


Mas é por pura diversão, pq o mundo do UNIX é bem silencioso..
Atualização: retirei mensagens de sucesso desnecessárias. Se ocorrer algum erro, você vai ficar sabendo.
Fiz uma expressão do Sed mais longa para substituir quase todos os caracteres de pontuação por '_'. Com essa lista, você pode personalizar o que substituir.
Também adicionei uma segunda passagem pelo sed para retirar traços baixos '_' repetidos que possam ter acumulado na primeira passagem do sed

Exs:
10-Pasta ._ com. _- espaços _hifens__e. pontos/ >>>  ./10_Pasta_com_espaços_hifens_e_pontos/
haha - text/ >>> ./haha_text/
____heydir/ >>> ./_heydir/
linux-firmware/ >>> ./linux_firmware/
pkgsInstalledPrevArchAndEtc/ >>> ./pkgsInstalledPrevArchAndEtc/
*[xxx]../ >>> ./_[xxx]_/



3. Re: Erro ao renomear muitas pastas[RESOLVIDO]

Jean César
dark777

(usa Linux Mint)

Enviado em 17/01/2020 - 12:57h

marimbondo2 escreveu:

Segue sugestão.
#!/bin/bash
# Uso: 1. entre no diretório pai que contém os dirs alvos
#
# 2. se quiser mover os diretórios para outra pasta:
# $ script.sh /OUTRA/PASTA/DESTINO #use caminho completo!
#
# do contrário, ele moverá os arquivos para a mesma pasta
# (renomeará somente)
#ref: https://www.vivaolinux.com.br/topico/Shell-Script/Erro-ao-renomear-muitas-pastasAJUDA/?pagina=1

#se não for especificado diretório de destino como primeiro argumento
#do script, usar o dir atual
TODIR="${1:-.}"

#se não houver, crie o diretório de destino
mkdir -p "${TODIR}" || exit 1

#criar lista de diretórios alvos
printf '%s\n' */ |
#enquanto lê a lista:
while read X; do
#processa o nome do diretório
if Y="$(sed -E '/\-|\s|\s$|\.|^\s/!{q100}; {s/^\s|\s-\s|\s|\s$|\.|__/_/g;}' <<<"${X}")"; then
#move e renomeia dirs
if mv "${X}" "${TODIR%/}/${Y}"; then
printf "Renamed %s to %s successfully.\n" "${X}" "${TODIR%/}/${Y}"
else
printf "%s: nothing done (2).\n" "${X}" 1>&2
fi
else
printf "%s: nothing done.\n" "${X}" 1>&2
fi
done



Mas é por pura diversão, pq o mundo do UNIX é bem silencioso..


testei seu codigo ontem a noite e ficou bom vc poderia me explicar o comando sed?
sed -E '/\-|\s|\s$|\.|^\s/!{q100}; {s/^\s|\s-\s|\s|\s$|\.|__/_/g;}'

wiki.anon


4. Re: Erro ao renomear muitas pastas[AJUDA]

Perfil removido
removido

(usa Nenhuma)

Enviado em 17/01/2020 - 17:24h

Meramente ajustei o código do Sed que você havia sugerido:

Ativei o módulo de expressões regulares estendida com -E, assim podemos usar o operador ' | ' (' ou ').

#se o sed não encontrar nenhum dos caracteres listados (o '\s' significa um espaço não quebrante)
#no nome do diretório, sair com o código '1000', e como esse código vai ser reconhecido
#pelo 'if', ele vai te direcionar para o 'else':
/\-|\s|\s$|\.|^\s/!{q100}

#caso passe, o Sed aplica a substituição que você sugeriu no código apresentado,
#só utilizei o operador ' | ' para retirar expressões repetidas:
{s/^\s|\s-\s|\s|\s$|\.|__/_/g;}


Mas ainda tem repetições que eu acho que são desnecessárias. Por exemplo, na expressões do Sed, '^\s' e '\s$' acho que já são reconhecidos somente com o '\s'.. Além disso, esse script é muito verbose.

Na realidade, como eu fiz o gerenciamento de erros manualmente, deveria ter silenciado o comando 'mv' com '>/dev/null' ou não ter feito o gerenciamento de erros nesse caso, totalmente desnecessário já que o Mv vai dizer se não conseguir mover o arquivo, mas enfim..

Por fim, se você modificar o comando do printf para " printf '%s\n' * ", retirando-se a barra '/' do glob, ele vai fazer a substituição em todos os arquivos, pastas e arquivos digamos normais, porém vai ignorar diretórios e arquivos que começam com um ' . ' .

Na verdade, eu fiz as alterações no post do script que mandei e você pode testar de novo, se quiser, com um código uma lista de caracteres mais longa que é possível personalizar. Vou salvar para mim também, sempre acontece de ter uns arquivos ou diretórios que quero deixar os nomes no tipo 'snake case'.



5. Re: Erro ao renomear muitas pastas[AJUDA]

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 17/01/2020 - 18:14h

Boa noite.
Sugestão para eliminar "espaços, hífen e pontos" e tudo mais que não for letra ou número.
pasta="10-Pasta ._ com. _- espaços _hifens__e. pontos"
sed -r 's/[^[:alnum:]]/_/g;s/_+/_/g' <<< ${pasta} 

10_Pasta_com_espaços_hifens_e_pontos
Ou
sed -r 's/_+/_/g' <<< ${pasta//[^[:alnum:]]/_} 

10_Pasta_com_espaços_hifens_e_pontos

______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________


6. Re: Erro ao renomear muitas pastas[RESOLVIDO]

Jean César
dark777

(usa Linux Mint)

Enviado em 20/01/2020 - 10:00h

marimbondo2 escreveu:

Meramente ajustei o código do Sed que você havia sugerido:

Ativei o módulo de expressões regulares estendida com -E, assim podemos usar o operador ' | ' (' ou ').

#se o sed não encontrar nenhum dos caracteres listados (o '\s' significa um espaço não quebrante)
#no nome do diretório, sair com o código '1000', e como esse código vai ser reconhecido
#pelo 'if', ele vai te direcionar para o 'else':
/\-|\s|\s$|\.|^\s/!{q100}

#caso passe, o Sed aplica a substituição que você sugeriu no código apresentado,
#só utilizei o operador ' | ' para retirar expressões repetidas:
{s/^\s|\s-\s|\s|\s$|\.|__/_/g;}


Mas ainda tem repetições que eu acho que são desnecessárias. Por exemplo, na expressões do Sed, '^\s' e '\s$' acho que já são reconhecidos somente com o '\s'.. Além disso, esse script é muito verbose.

Na realidade, como eu fiz o gerenciamento de erros manualmente, deveria ter silenciado o comando 'mv' com '>/dev/null' ou não ter feito o gerenciamento de erros nesse caso, totalmente desnecessário já que o Mv vai dizer se não conseguir mover o arquivo, mas enfim..

Por fim, se você modificar o comando do printf para " printf '%s\n' * ", retirando-se a barra '/' do glob, ele vai fazer a substituição em todos os arquivos, pastas e arquivos digamos normais, porém vai ignorar diretórios e arquivos que começam com um ' . ' .

Na verdade, eu fiz as alterações no post do script que mandei e você pode testar de novo, se quiser, com um código uma lista de caracteres mais longa que é possível personalizar. Vou salvar para mim também, sempre acontece de ter uns arquivos ou diretórios que quero deixar os nomes no tipo 'snake case'.


eu testei o primeiro codigo com a expressão sed que estava lá porem ele ainda nao reconhece espaços em branco ou o excesso dos mesmos, tanto a direita do ifem quando a esquerda ainda nao entendi direito pq isso ocorreu:

bash$ mkdir "Nova pasta.DRift- Asdf java" "Nova pasta.DRift -Asdf Java" "Nova pasta .DRift -Asdf Java" "Nova pasta. DRift- Asdf Java"

ao executar o script ele renomeia para algo como:

Nova_pasta.DRift-__ Asdf java
Nova_pasta.DRift__-Asdf__Java
Nova_pasta _.DRift_-Asdf_Jhava
Nova_pasta.__ DRift-__Asdf__JHava"

seria interessante uma lista mais completa vou fazer mais testes nestes scripts que estão aqui estudar os comandos sed, em relação as repetiçoes nem senpre funciona com \s nao seu se tem alguma coisa a ver com o interpretador #!/bin/bash ou #!/bin/sh .
wiki.anon


7. Re: Erro ao renomear muitas pastas[AJUDA]

Perfil removido
removido

(usa Nenhuma)

Enviado em 20/01/2020 - 11:05h

Faça as modificações necessárias.

Eu atualizei o script, como mencionei, optei por uma segunda passagem do Sed para limpar o excesso de ___ nos nomes. NA VERDADE, dá sim para colocar tudo em um só comando do Sed. É só especificar cada comando que quer executar no text com '-e' antes..
Mas cuidado: por exemplo: { sed -e 's/ - /_/g' -e 's/ -/_/g' -e 's/ /_/g' } é uma sintaxe que você tem que tomar cuidado, pois nesse caso o texto passará pelas três expressões, mas a cada passagem ele terá sido modificado pela expressão anterior já..
Então você pode ir aperfeiçoando isso..

Neste caso específico, também deixei de usar '\s' para usar um simples espaço em branco ' '. Isso se deve ao fato que '\s' dentro de uma lista '[..]', é lido como caracteres separados, ou seja, ele lê '\' e 's'.. Então '\s' só funciona como 'non-breaking space' fora de listas , e na primeira expressão do comando do Sed ( 's/\sESTA/ /g' ) , pois a segunda parte da expressão não é uma expressão regular ( 's/\s/ ESTA/g' ). OK?

Como falei, fiz modificações naquele comando do Sed por que estava dando alguns probleminhas e conflitos com a expressão do Sed original..


8. Re: Erro ao renomear muitas pastas[RESOLVIDO]

Jean César
dark777

(usa Linux Mint)

Enviado em 31/01/2020 - 15:54h

marimbondo2 escreveu:

Faça as modificações necessárias.

Eu atualizei o script, como mencionei, optei por uma segunda passagem do Sed para limpar o excesso de ___ nos nomes. NA VERDADE, dá sim para colocar tudo em um só comando do Sed. É só especificar cada comando que quer executar no text com '-e' antes..
Mas cuidado: por exemplo: { sed -e 's/ - /_/g' -e 's/ -/_/g' -e 's/ /_/g' } é uma sintaxe que você tem que tomar cuidado, pois nesse caso o texto passará pelas três expressões, mas a cada passagem ele terá sido modificado pela expressão anterior já..
Então você pode ir aperfeiçoando isso..

Neste caso específico, também deixei de usar '\s' para usar um simples espaço em branco ' '. Isso se deve ao fato que '\s' dentro de uma lista '[..]', é lido como caracteres separados, ou seja, ele lê '\' e 's'.. Então '\s' só funciona como 'non-breaking space' fora de listas , e na primeira expressão do comando do Sed ( 's/\sESTA/ /g' ) , pois a segunda parte da expressão não é uma expressão regular ( 's/\s/ ESTA/g' ). OK?

Como falei, fiz modificações naquele comando do Sed por que estava dando alguns probleminhas e conflitos com a expressão do Sed original..


Fiz algumas alterações no comando sed e aparentemente esta funcionando, pois coloquei também para retirar tabs e espaços no início e fim do nome.

#!/bin/bash

#Renomeia apenas diretórios

# Uso: 1. entre no diretório pai que contém os dirs alvos
#
# 2. se quiser mover os diretórios para outra pasta:
# $ rendir-3 /OUTRA/PASTA/DESTINO #use caminho completo!
#
# do contrário, ele moverá os arquivos para a mesma pasta somente renomeando os mesmos
#ref: https://www.vivaolinux.com.br/topico/Shell-Script/Erro-ao-renomear-muitas-pastasAJUDA/?pagina=1
#
#bash$ mkdir " Nova pasta.DRift - asdf java "
#bash$ mkdir " Nova pasta.DRift- Asdf java "
#bash$ mkdir " Nova pasta.DRift - asdf Java "
#bash$ mkdir " Nova pasta.DRift -Asdf Java "
#bash$ mkdir " Nova pasta.DRift- asdf jAvA "
#bash$ mkdir " Nova pasta.DRift- Asdf jAvA "
#bash$ mkdir " Nova pasta.DRift -asdf JaVa "

#lista apenas diretórios
#DIRECTORY="$(ls -d */)"

#se não for especificado diretório de destino como primeiro argumento
#do script, usar o dir atual
IFS='
'

TODIR="${1:-.}"

#se não houver, crie o diretório de destino
mkdir -p "${TODIR}" || exit 1

#criar lista de diretórios alvos
printf '%s\n' */ |
#enquanto lê a lista:
while read X; do
#processa o nome do diretório
#remove espaço em branco no início do nome e no fim do nome "s/^\s*//g;s/\s*$//g;"
#substitui ponto por underline "s/\./_/g;"
#substitui traço com espaço em branco por underline a direita e a esquerda "s/-\s/_/g;s/\s-/_/g;"
#substitui espaço em branco por underline "s/\s/_/g;"
#substitui dois ou mais underlines por um underline "s/__*/_/g;"
#remove barra no fim do nome "s/\/$//g;"
#remove um ou dois underlines no inicio e fim do nome "s/^__*//g;s/__*$//g;"
#PS: para que seja removido algum underline no final do nome é nescessário retirar a barra no fim do nome "s/\/$//g;s/^__*//g;s/__*$//g;"
Y="$(sed -E 's/^\s*//g;s/\s*$//g;s/\./_/g;s/-\s/_/g;s/\s-/_/g;s/\s/_/g;s/__*/_/g;s/\/$//g;s/^__*//g;s/__*$//g;' <<<"${X}")"

#move e renomeia dirs
mv "${X}" "${Y}"
if [ $? -ne 0 ]; then
printf "\033[37;1m\n\"%s\" \033[m<-\033[31;1m nothing done.!!\n\n\033[m" "${X/\//}" 1>&2
else
printf "\033[36;1m\nRenamed \033[31;1m\"\033[m%s\033[31;1m\"\033[36;1m to \033[31;1m\"\033[33;1m%s\033[31;1m\" \033[36;1msuccessfully\033[m\n\n" "${X/\//}" "${Y/\//}"
fi
done

#Renamed " Nova pasta.DRift - asdf java " to "Nova_pasta_DRift_asdf_java" successfully

#Renamed " Nova pasta.DRift- Asdf java " to "Nova_pasta_DRift_Asdf_java" successfully

#Renamed " Nova pasta.DRift - asdf Java " to "Nova_pasta_DRift_asdf_Java" successfully

#Renamed " Nova pasta.DRift -Asdf Java " to "Nova_pasta_DRift_Asdf_Java" successfully

#Renamed " Nova pasta.DRift- asdf jAvA " to "Nova_pasta_DRift_asdf_jAvA" successfully

#Renamed " Nova pasta.DRift- Asdf jAvA " to "Nova_pasta_DRift_Asdf_jAvA" successfully

#Renamed " Nova pasta.DRift -asdf JaVa " to "Nova_pasta_DRift_asdf_JaVa" successfully

#Renamed " Nova pasta.DRift -Asdf JaVa " to "Nova_pasta_DRift_Asdf_JaVa" successfully
wiki.anon






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts