긴 이름의 Linux mv 파일


19

리눅스에서는 때때로 다음과 같이 파일 이름을 바꿉니다.

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

파일을 다른 디렉토리로 옮기지 말고 파일 이름 만 바꾸고 싶습니다.

해당 명령의 속기 버전을 수행 할 수있는 명령이 있습니까? 나는 다음과 같은 것을 생각하고있다 :

mv dir1/dir2/dir3/file.txt  file.txt.old

또는 아마도 (이름에 추가하기 위해)

mv dir1/dir2/dir3/file.txt  {}.old

내 목표는 전체 경로를 다시 지정할 필요가 없습니다.

필자가 쓴 "예제"가 효과가 없다는 것을 알고 있지만, 내가 달성하고자하는 것에 대한 아이디어 일뿐입니다.

나는 디렉토리에 cd를 넣고 싶지 않다.


8
왜 디렉토리로 바꾸지 않습니까? 빠르고 문제를 해결합니다.
Michael Hampton

이 같은 위치에서 많은 하위 디렉토리를 다루고 있습니다. 매번이 부모 디렉토리로 돌아와야한다면 느려집니다
santiago arizti

3
아무도 당신이 원하는 다른 디렉토리로 변경해야한다고 말하지 않았습니다.
Michael Hampton

참고 (cd dir1/dir2/dir3 && exec mv file.txt{,.old})때문에, 서브 프로세스없이 코드를 효과적으로 동일한 성능을 가지고 exec을 피가 fork()정확히 하나의 포크 어느 쪽이든 그래서, 외부 명령 호출시 보내고.
찰스 더피

답변:


45

단일 파일 시도

mv dir1/dir2/dir3/file.{txt,txt.old}

를 Where X{a,b}구조가 확장 Xa Xb, 당신은 사용하여 미리보기를 할 수 있습니다

echo dir1/dir2/dir3/file.{txt,txt.old}

그것이 당신의 필요에 맞는지 확인하십시오.

노트:

  1. 여러 파일의 경우

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

원하는 것으로 확장되지 않을 것입니다. (이것은 file.txt file1.txt.old file2.txt의 혼합으로 확장됩니다 ...)

  1. {txt,txt.old}{,.old}의견 에 따라 단축 될 수있다

  2. 디렉토리 이름이 명확한 경우 와일드 카드를 사용할 수 있습니다.

    mv *1/*2/d*/*.{,old}
    

여러 파일 사용 rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

-n효과적인 이름을 바꾸려면 드롭하십시오 .


1
좋아, 나는이 확장 방법을 몰랐다! 감사합니다
santiago arizti

14
겠습니까 mv dir1/dir2/dir3/file.txt{,.old}도 작동, 심지어 짧은하지?
Josh

3
@ 조쉬 네 완벽하게 작동하고 적은 키 입력이 필요합니다. 나는이 구성을 매우 정기적으로 사용합니다.
rlf

2
수년 동안 리눅스 쉘을 사용하는 방법은 여전히
재밌다.

만약 내가 배쉬 언어로 공식적인 훈련을 받았다면이 모든 "트릭"이 더 분명 할 것 같다.
santiago arizti

6

이 명령 rename은 일치하는 모든 파일의 이름을 바꿉니다. 주요 목적은 여러 파일의 이름을 바꾸는 것이지만 Perl식이 하나의 파일과 만 일치하면이 단일 파일의 이름 만 바꿉니다. 자세한 내용과 배포 판별 구문은 맨 페이지를 참조하십시오 man rename.

사용법 예 : "/path/file.txt"의 이름을 "/path/file.txt.old"로 바꾸십시오.

rename 's/file.txt/file.txt.old/g' /path/file.txt

짧은 표기법 (샬롬 덕분에) :

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

드라이 런 사용 rename -n.

더 많은 예제와 세부 사항은 https://thepcspy.com/read/bulk-rename-files-in-ubuntu/ 에서 찾을 수 있습니다


쿨, 나는 rename 명령에 대해 알았지 만, 그것이 할 수있는 모든 것을 알지 못했습니다. 감사합니다!
santiago arizti

6
불행히도 다른 Linux 배포판에는 rename완전히 다른 동작을 가진 다른 명령이 있습니다.
kasperd

1
추가하여 이름 변경이 특정 작업을 위해 .old파일 이름에, 그것은 할 아마 좀 더 편리 rename 's/$/.old/' /path/to/file.txt또는rename '$_.=".old"' /path/to/file.txt
shalomb

@Fabian-nitpicking이 아니 었습니다. OP가 찾고있는 자주 사용되는 관용구 인 것처럼 보이는 "가장 짧은 손"을 목표로합니다 :)
shalomb

4

일회성 경우 현재 디렉토리를 변경하지 않으려면 하위 쉘을 사용할 수 있습니다.

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

cd하위 쉘 내부에 있기 때문에 실제 쉘에서 디렉토리를 변경하지 않았습니다.


4
더 빠르고 안전한 사용 && exec mv- cd실패시 이름 바꾸기를 시도하지 않고 exec서브 쉘을 소비하므로 성능 저하를 피할 수 있습니다.
찰스 더피

에 동의 && 내가 말했듯이, 나는 서브 쉘의 비용에 대해 걱정하지 (간단하게 : 수있는 것은 쉽게는 IMO 더 중요하는 방법을 기억하는) 것, 일회성의 경우를 들어
아담

한 가지 방법 만 기억한다면 효율적인 방법을 기억하면 비효율적 인 길을가는 것이 중요 하지 않은지 확인하는 데 도움이됩니다 .
Charles Duffy

4

명령 줄을 이미 시작했을 때 사용할 수 있기 때문에 @} 확장을 사용하는 @archemar의 솔루션이 마음에 듭니다. 완전성을위한 다른 가능성은 다음과 같습니다.

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(따옴표는 공백이나 다른 단어 분리 문자가있는 경우에만 필요합니다)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

노트:

  • 이것은 bash 구문입니다. 다른 쉘을 사용 중일 수 있습니다
  • mymv 합리적인 문자열이 될 수 있습니다. "my move"에 mymv를 사용했습니다.
  • 함수 정의는 .bash_profile에 넣을 수 있습니다

다른 것:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

그러나

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(@Adam 및 @CharlesDuffy)는 CD가 실패하는 경우에 더 좋습니다.


1
를 사용하지 마십시오 mmv. 이러한 이름의 프로그램이 이미 있습니다.
glglgl

1
@glglgl 완료 :)
Law29

2

mv명령 을 줄이기 위해 서브 디렉토리를 입력하려고 하지만 나중에 현재 디렉토리로 돌아가려면 두 가지 방법이 있습니다. 하나는 cdand mv를 서브 쉘 에 넣는 것입니다 (이미 제안 된 바와 같이).

다른 하나는 디렉토리 를 사용 pushd하고 popd변경하는 것입니다.

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

pushd명령처럼 cd먼저 스택에 현재 디렉토리의 이름을 밀어 제외. popd스택에서 최상위 이름을 제거하고 해당 디렉토리로 변경합니다.


pushdpopd대화 형 사용하도록 확장입니다 - POSIX 명시 적으로 나열 그들로 "결과는 명시되지"및 쉘 스크립트를 실행하기위한 내장 필요를 지원하지 (즉, 최소한의 임베디드 환경에.).
Charles Duffy

2

난 그냥 할거야

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory

0

관련된 솔루션 mv something{.txt,.txt.old}은 "bashism"을 사용하고 있습니다. 일반적인 변수 조작을 사용하여보다 이식 가능한 방법을 원한다면 :

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"

2
적절한 POSIX 사양 은 pubs.opengroup.org/onlinepubs/009695399/utilities/… 를 참조하십시오 ${var/text/replacement}.
Charles Duffy

@CharlesDuffy oh ... 당신은 나를 슬프게합니다 :(
Olivier Dulac
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.