sed 또는 이름 바꾸기를 사용하지 않고 디렉토리 이름을 재귀적으로 바꾸는 방법은 무엇입니까?

sed 또는 이름 바꾸기를 사용하지 않고 디렉토리 이름을 재귀적으로 바꾸는 방법은 무엇입니까?

"열병"이 포함된 일부 디렉토리의 이름을 "말라리아"가 포함되도록 바꾸려고 합니다. 이 명령어는 sed를 사용하거나 이름을 바꾸지 않고 이 작업을 수행합니다. 지금까지 내 오류에는 주로 mv: cannot stat ‘retest\nretest/Section-01\nretest/Section-02\nretest/Section-03\nretest/Section-04’: No such file or directory.

내 코드가 수행하는 가장 좋은 작업은 첫 번째 수준에서 디렉터리 이름을 바꾸는 것입니다.

이것은 내 디렉토리 구조입니다.

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

지금까지 내 코드는 다음과 같습니다

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

제가 고려한 또 다른 접근 방식은 다음과 같은 함수를 사용하는 것이었지만 그 역시 작동하지 않았습니다.

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

답변1

Don Crissti가 언급했듯이 이 문제를 해결하는 방법은 여러 가지가 있습니다 find. 하지만 우리는 두 개의 디렉터리 수준에 대해서만 이야기하고 있기 때문에 단 하나의 외부 명령을 사용하여 약간 다른 방식으로 이 작업을 수행할 수 있다고 생각합니다.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 .

결과:

$ 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

답변2

무엇에 대해:

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

이 작업이 가능해야 합니다. (startdir을 시작 디렉토리로 변경)

이 조회는 "Fever"가 포함된 디렉터리만 반환합니다. mv 명령은 bash 인라인 대체를 사용하여 Fever가 Malaria로 변경된 문자열을 반환합니다.

-깊이를 추가하면 하위 디렉터리를 먼저 처리합니다.

관련 정보