
더 많은 사용자의 tmp
홈 디렉토리에 디렉토리가 있다고 가정합니다. tmp
모든 사용자의 홈 디렉터리에 있는 모든 디렉터리의 이름을 바꾸고 싶습니다 . 가장 쉬운 방법은 무엇입니까?
이 같은:
sudo mv /home/*/tmp /home/*/temp
아니요.
이 같은:
for dir in /home/*; do
if [ -d $dir/tmp ]; then
mv $dir/tmp $dir/temp
fi
done
너무 많은 것 같습니다.
답변1
Perl은 rename(1)
대부분의 Linux 시스템에 설치된 명령과 함께 제공됩니다. Debian 기반 시스템에서는 /usr/bin
이 경우 다음과 같이 사용할 수 있습니다.
$ rename 's/tmp$/temp/' /home/*/tmp
첫 번째 매개변수는 새 이름의 후속 매개변수를 생성하는 데 사용되는 Perl 표현식입니다. 그런 다음 해당 표현식의 결과에 따라 각각의 이름이 변경됩니다.
홈 디렉터리에 이미 이름이 지정된 파일/디렉토리가 있으면 temp
해당 디렉터리에 대해서만 오류가 발생하고 rename
계속 진행합니다.
/home/c/tmp not renamed: /home/c/temp already exists
먼저 해당 플래그를 사용하여 실행 하여 -n
실제로 실행하지 않고도 이름 바꾸기가 수행하는 작업을 확인하고 모든 것이 올바르게 보이는지 확인할 수 있습니다. 그런 다음 내려놓고 -n
제 역할을 하게 하세요.
답변2
sudo find /home -maxdepth 2 -type d -name 'tmp' -execdir mv {} temp \;
여기서는 maxdepth
현재 디렉터리에서 최대 2개 수준만 찾아야 합니다. 또한, execdir
찾은 파일의 위치를 변경하여 후속 명령을 실행하도록 지정합니다.
답변3
질문의 두 번째 옵션을 단축하기 위해 제가 생각할 수 있는 유일한 방법은 다음과 같습니다.
for dir in /home/*;do
[ -d $dir/tmp ] && mv -n $dir/t{,e}mp
done
그러나 이는 가독성을 어느 정도 감소시킵니다. 는 t{,e}mp
쉘에 의해 두 단어 tmp
와 로 확장됩니다 temp
. 따라서 명령줄은 로 확장됩니다 mv <contents of $dir>/tmp <contents of $dir>/temp
. 일반적으로 셸은 prefix_{a,b,c}_suffix
로 확장됩니다 prefix_a_suffix prefix_b_suffix prefix_c_suffix
. 빈 위치(예: 의 첫 번째 위치)는 {,e}
빈 문자열로 확장됩니다.
다음과 같은 작업을 수행할 수도 있습니다 perl
.
perl -e '
@a=grep {-d} glob "/home/*/tmp";
map { rename $_ => $_=~ s/tmp\Z/temp" } @a
'
하지만 나는 여전히 원본 버전이 충분하다고 생각합니다.
편집하다
이 문제에 대한 Michael Kjörling의 의견에서 언급했듯이 스위치가 존재하는 경우 충돌하지 않도록 하기 위해 -n
스위치가 추가되었습니다 . 펄 버전mv
$dir/temp
~ 할 것이다temp
존재하는 경우 파기합니다.
답변4
이동 문을 생성하고 한 번에 모두 평가합니다.
ls -d /home/*/tmp | sed 's/.*t/mv &mp &e/' | sh -xv