답변:
마지막 인수가 디렉토리 인 경우, 현재 작업 디렉토리의 모든 파일과 디렉토리 (이름이 점으로 시작하는 디렉토리 제외)를 해당 디렉토리로 이동했습니다. 두 개의 파일이 있으면 첫 번째 파일이 두 번째 파일을 덮어 썼을 수 있습니다.
다음은 몇 가지 데모입니다.
둘 이상의 파일과 마지막 인수는 파일입니다
$ mkdir d1 d2 d3
$ touch a b c e
$ mv *
mv: target 'e' is not a directory
두 개 이상의 파일과 마지막 인수는 디렉토리입니다
$ mkdir d1 d2 d3
$ touch a b c
$ mv -v *
'a' -> 'd3/a'
'b' -> 'd3/b'
'c' -> 'd3/c'
'd1' -> 'd3/d1'
'd2' -> 'd3/d2'
두 개의 파일
$ touch a b
$ mv -v *
'a' -> 'b'
추가 설명
쉘은 glob ( *
)를 인수로 확장합니다 mv
. 글로브는 일반적으로 알파벳 순서로 확장됩니다. mv
항상 파일과 디렉토리 목록을 봅니다. 글로브 자체는 절대 보지 않습니다.
이 명령 mv
은 두 가지 유형의 이동을 지원합니다. 하나는 mv file ... directory
입니다. 다른 하나는 mv old-file-name new-file-name
(또는 mv old-file-name directory/new-file-name
)입니다.
먼저 5 개의 파일과 1 개의 폴더를 테스트베이스로 만들겠습니다.
touch file1 file2 file3 file4 file5
mkdir folder
다음으로 테스트 명령을 실행하겠습니다. 이 -v
옵션은 쉘이 실행하는 모든 명령을 인쇄하도록 지정 stderr
합니다. -x
I가 인쇄 같은 원하는 옵션을 지정 stderr
- 하지만 나는 그것이 수행하려는 후 명령이 평가하지만 전에 쉘을 실행합니다.
sh -cxv 'echo mv *'
echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder
따라서 쉘에 공급하는 명령이 echo mv *
있고 확장 후 쉘이 실행하는 명령 뒤에 모든 파일과 폴더가 있음을 알 수 있습니다.*
echo mv
기본적으로 쉘은 다음과 같이 글로브 를 확장합니다 .
sh -cxv 'echo file[1-5]'
echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5
이것은 set [+-]f
glob 함수 의 결과입니다 .
sh -cxvf 'echo file[1-5]'
echo file[1-5]
+ echo 'file[1-5]'
file[1-5]
따라서 쉘과 같은 기본 옵션으로 구성된 쉘에서 명령을 실행 하면 현재 디렉토리에있는 모든 파일의 인수 목록이 로케일에 따라 정렬되어 단어 mv *
로 확장 *
됩니다. 그것은 콜 수행 exec(ve)
에 대한 mv
(기본적으로) 추가 된이 인수리스트를. 그래서 mv
쉘이 그것들을 움켜 잡고 분류함에 따라 모든 인수를 얻습니다. strace
이러한 효과를 보는 것 외에도 다음과 같이 디버그를 다시 사용할 수 있습니다.
sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT
sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder
그리고 포터블 :
( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1
: /mv/file1/file2/file3/file4/file5/folder/
기본적으로 쉘은 mv
디렉토리의 내용 (비어 있지 않고 이름이 시작되는 파일 / 폴더를 포함하지 않는 경우 .
) 을 인수 목록으로 사용하여 실행됩니다. mv
같은 방법으로 - POSIX는이 두 개 이상의 인수로 불려 갔을 경우 디렉토리로 최종 인수를 해석하는 지정 ln
입니다 (사실, 그들은 기능을 기본에 매우 유사한 도구를 것 때문에) .
echo
그래도 충분합니다 .
sh -cxv 'mv *' ; ls
mv *
+ mv file1 file2 file3 file4 file5 folder
folder/
모든 파일은 폴더이기 때문에 최종 인수로 이동되었습니다. 폴더가 아닌 경우 어떻게해야합니까?
sh -cxv 'cd *; mv *'; ls . *
cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory
.:
folder/
folder:
file1 file2 file3 file4 file5
이 경우 POSIX가 지정 mv
해야하는 방식입니다.
mv [-if] source_file target_file
mv [-if] source_file... target_dir
첫 번째 시놉시스 양식에서,
mv
유틸리티는 source_file 피연산자에 의해 명명 된 파일을 target_file에 의해 지정된 목적지로 이동해야합니다 . 이 첫 번째 개요 양식은 최종 피연산자가 기존 디렉토리의 이름을 지정하지 않고 기존 디렉토리를 참조하는 기호 링크가 아닌 경우에 가정합니다. 이 경우, source_file 이 비 디렉토리 파일 이름을 지정하고 target_file 이 후행/slash
문자로 끝나는mv
경우이를 오류로 취급하고 source_file 피연산자가 처리 되지 않습니다 .두 번째 개요 양식에서
mv
source_file 피연산자가 명명 한 각 파일을 target_dir 피연산자가 명명 한 기존 디렉토리의 대상 파일로 이동 하거나 target_dir 이 기존 디렉토리를 참조하는 심볼릭 링크 인 경우 참조해야합니다. 각 source_file의 대상 경로는 대상 디렉토리의 연결/slash
, 대상이로 끝나지 않은 경우 단일 문자/slash
및 source_file 의 마지막 경로 이름 구성 요소입니다 . 이 두 번째 형식은 최종 피연산자가 기존 디렉토리의 이름을 지정할 때 사용됩니다.
따라서 *
확장하면 :
두 개의 파일
renamed
두 번째 파일이 첫 번째 에서 두 번째 파일 인 파일은 하나만 있어야합니다 unlinked
.하나 이상의 파일 다음에 디렉토리 또는 하나의 링크가 마지막에 옴
다른 것
sh
것을 사용하면 디버깅을 잊어 버렸지 만 원래 질문에 관해서는 문제가 쉘이 아니라는 것을 의미 mv
합니까? 그것은 불쾌합니다. 원래 생각했던 것보다 간단하지만 실제 함정입니다.
*
단일 인수가 아닙니까? 권리? :)
먼저 셸 ./*
은 현재 디렉토리의 모든 파일로 확장 됩니다 (점으로 시작하는 파일 제외).
mv
실패mv
실패합니다.echo ./*
쉘 사용 (일반적으로 알파벳)를 주문 확인할 않습니다.
mv
하나의 인수로만 호출되면 오류 메시지를 리턴합니다.
missing destination file operand after *filename*
어제 그래도 내 역사의 동일한 명령이 이제 제공합니다 .
무엇을
mv *
합니까?
더 짧은 대답은 다음과 같습니다.
쉘은 와일드 카드 *
를 디렉토리 내용 목록으로 확장합니다 . 그런 다음 쉘은 해당 전체 목록을 명령에 전달합니다. 명령이 보이지 않습니다 *
.
이 명령 mv file1 file2 ... filen directory
은 file1 ... filen을 디렉토리로 이동합니다.
여기에 세 개의 파일을 포함하는 테스트 디렉토리를 만듭니다.
$ mkdir t
$ cd t
$ echo a>a; echo b>b; echo c>c
$ ls
a b c
여러 파일을 단일 파일로 이동할 수 없습니다
$ mv *
mv: target `c' is not a directory
서브 디렉토리를 추가하자
$ mkdir d
여러 파일을 하위 디렉토리로 옮길 수 있습니다
$ mv *
$ ls
d
$ ls d
a b c
mv file1 file2 ... filen directory
은 전혀 관련이 거의 없습니다 *
.
*
로는file dir
있는 일부 로케일이 없으면 d
다음은 f
.
a b c d
입니다 file ... dir
. 나는 당신이 어디서나 정렬을 언급하지 않고 단지 그 말만하기 때문에 전혀 언급하지 않았습니다.*
하게 file ... dir
발생하지 않는다.