Return 키를 누르기 전에 실수로 대상을 지정하는 것을 잊었습니다. mv ./*
대상을 지정 하지 않고 현재 디렉토리 아래의 파일과 디렉토리를 어디로 이동합니까?
답변
마지막 인수가 디렉토리 인 경우, 현재 작업 디렉토리의 모든 파일과 디렉토리 (이름이 점으로 시작하는 디렉토리 제외)를 해당 디렉토리로 이동했습니다. 두 개의 파일이 있으면 첫 번째 파일이 두 번째 파일을 덮어 썼을 수 있습니다.
다음은 몇 가지 데모입니다.
둘 이상의 파일과 마지막 인수는 파일입니다
$ 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
.
-
하나 이상의 파일 다음에 디렉토리 또는 하나의 링크가 마지막에 옴
- 하나의 디렉토리 또는 하나의 링크 만 있어야합니다. 디렉토리는 모든 상위의 이전 내용이 이동 된 곳입니다.
-
다른 것
- 오류 메시지와 만족스러운 한숨의 안식이 있어야합니다.
답변
먼저 셸 ./*
은 현재 디렉토리의 모든 파일로 확장 됩니다 (점으로 시작하는 파일 제외).
- 파일이 없거나 하나만있는 경우 :
mv
실패 - 두 개의 파일이있는 경우 : 첫 번째 파일이 두 번째 파일로 이동하여 손실 됨
- 파일이 두 개 이상인 경우 :
- 마지막 파일이 디렉토리 인 경우 : 모든 파일이이 디렉토리로 이동됩니다
- 그렇지 않으면
mv
실패합니다.
답변
입력하면 mv ./*
셸이 확장되어 ./*
실행 mv
됩니다.
몇 가지 참고할 사항 :
- 경우
./*
보다 2 개 인자로 확장되고,mv
논리적 오류를 생성합니다. ./*
일반적으로 점으로 시작하지 않고 현재 디렉토리에있는 모든 파일 (디렉토리 포함)로 확장됩니다../*
쉘 문서를 읽어서 확장되는 내용을 제어 할 수 있습니다 (man 7 glob
주제에 대한 진입 점임). 다른 쉘에는 다른 옵션이 있습니다.
답변
무엇을
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