Como se pode renomear recursivamente diretórios sem sed ou renomear?

0

Estou tentando renomear alguns diretórios que contêm "Fever" para conter "Malária". A instrução é fazer isso sem sed ou renomear. Até agora, meus erros incluem principalmente linhas como mv: cannot stat ‘retest\nretest/Section-01\nretest/Section-02\nretest/Section-03\nretest/Section-04’: No such file or directory .

O melhor que o meu código fez foi renomear os diretórios no primeiro nível.

Aqui está minha estrutura de diretórios:

Fever-A/Malaria-A-A

Fever-B/Fever-B-A

Fever-B/Fever-B-B

Fever-C/Malaria-A

Fever-C/Fever-C-A

Fever-C/Fever-C-B

Fever-C/Fever-C-C-C

Fever-D/Malaria-A

Fever-D/Malaria-B

O código que tenho até agora é:

#!/bin/bash

# Access directory
#cd $1

# Find all subdirectories in $1 and load up array
all=($(find $1 -type d))
#echo ${all[@]}

# Loop through directories above
for dir in ${all[@]}
do
    # echo "$dir"
    cd $dir
    # List files with "Section" in name
    subdir=(:"Section*")

    # A second loop for directories in each dir with "Section*"
    for item in ${subdir[@]}
    do
            echo $item
            echo "--------------------"

            # Rename operation
            mv $item ${item//Fever/Malaria}
    done
    cd $1
done

Outra abordagem que considerei é usar uma função como essa, mas também não está funcionando:

#!/bin/bash

rename(){
    old_names=($(find $1 -maxdepth 1 -type d))

    for item in ${old_names[@]}
    do
            if [[ $item = *Section* ]]; then
                    new_name=${item//Fever/Malaria}
                    mv $item $new_name
            elif [[ $1 != $item ]]; then
                    rename $item
            fi

            rename $1
    done
}

rename $1
    
por IshMary 29.07.2016 / 00:14

2 respostas

1

Como Don Crissti menciona, existem várias maneiras de resolver isso com find . Mas eu pensei, já que estamos falando apenas de dois níveis de diretório, que podemos fazer isso de forma ligeiramente diferente com apenas um comando externo: mv

#!/bin/bash

fixdir()
{
  local f g

  for f in Fever*
  do
    if [ -e "$f" ]
    then
      g=Malaria"${f#Fever}"
      if [ -e "$g" ]
      then
        echo "Skipping $1/$f->$1/$g; already exists"
      else
        # echo "Renaming $1/$f->$1/$g"
        mv "$f" "$g"
      fi
    fi
  done
}

for a in *
do
  if [ -d "$a" ]
  then
    (cd $a ; fixdir $a )
  fi
done

fixdir .

Os resultados:

$ ls -1d F*/*
Fever-A/Malaria-A-A
Fever-B/Fever-B-A
Fever-B/Fever-B-B
Fever-C/Fever-C-A
Fever-C/Fever-C-B
Fever-C/Fever-C-C-C
Fever-C/Malaria-A
Fever-D/Malaria-A
Fever-D/Malaria-B

$ ./fix

$ ls -1d M*/*
Malaria-A/Malaria-A-A
Malaria-B/Malaria-B-A
Malaria-B/Malaria-B-B
Malaria-C/Malaria-A
Malaria-C/Malaria-C-A
Malaria-C/Malaria-C-B
Malaria-C/Malaria-C-C-C
Malaria-D/Malaria-A
Malaria-D/Malaria-B
    
por 29.07.2016 / 00:58
0

E sobre:

for dir in $(find /startdir -depth -type d -name '*Fever*')
do   dn=$(basename $dir)
     mv $dir $(dirname $dir)/${dn//Fever/Malaria}
done

Isso deve ser feito. (Altere o startdir para o diretório inicial)

O achado só retornará diretórios contendo 'Fever'. o comando mv usa a substituição em linha do bash para retornar uma string com Fever alterada para Malaria.

A profundidade adicionada faz com que ele processe os subdiretórios primeiro.

    
por 29.07.2016 / 00:30