파일 이름을 변경하여 확장명을 변경하고 효과적으로 달성하려고합니다.
mv *.txt *.tsv
그러나 이것을 할 때 나는 얻는다 :
* .tsv는 디렉토리가 아닙니다
처음 10 개의 Google 히트 쇼 mv
가 이와 같이 작동 한다는 것이 다소 이상하다고 생각합니다.
파일 이름을 변경하여 확장명을 변경하고 효과적으로 달성하려고합니다.
mv *.txt *.tsv
그러나 이것을 할 때 나는 얻는다 :
* .tsv는 디렉토리가 아닙니다
처음 10 개의 Google 히트 쇼 mv
가 이와 같이 작동 한다는 것이 다소 이상하다고 생각합니다.
답변:
명령을 실행할 때 :
mv *.txt *.tsv
쉘은 bash는 가정 할 수 확장 와일드 카드를 경우 (디렉토리 포함) 일치하는 파일이 있습니다. 파일 목록은 여기 프로그램으로 전달됩니다 mv
. 일치하는 것이 없으면 확장되지 않은 버전이 전달됩니다.
다시 : 쉘 은 프로그램이 아닌 패턴을 확장합니다.
많은 예제가 아마도 가장 좋은 방법 일 것입니다.
$ ls
file1.txt file2.txt
$ mv *.txt *.tsv
이제 mv
줄 에서 일어나는 일은 쉘*.txt
이 일치하는 파일로 확장 된다는 것입니다. *.tsv
변경되지 않은 파일이 없습니다.
이 mv
명령은 두 가지 특수 인수로 호출 됩니다 .
argc
: 프로그램을 포함한 인수 수argv
: 첫 번째 항목으로 프로그램을 포함하는 인수 배열.위의 예에서 다음과 같습니다.
argc = 4
argv[0] = mv
argv[1] = file1.txt
argv[2] = file2.txt
argv[3] = *.tsv
mv
마지막 인수는 경우 프로그램의 체크를 확인합니다 *.tsv
, 디렉토리입니다. 그렇지 않기 때문에 프로그램은 파일을 연결하도록 설계되지 않았으므로 계속 진행할 수 없습니다. (일반적으로 모든 파일을 하나로 이동하십시오.) 또한 변덕스러운 디렉토리를 만들지 마십시오.
결과적으로 오류를 중단하고보고합니다.
mv: target ‘*.tsv’ is not a directory
이제 당신이 대신 말하면 :
$ mv *1.txt *.tsv
mv
명령으로 실행한다 :
argc = 3
argv[0] = mv
argv[1] = file1.txt
argv[2] = *.tsv
이제 다시 존재 mv
하는지 확인하십시오 *.tsv
. 파일 file1.txt
이로 이동 하지 않기 때문에 *.tsv
. 즉, 파일 이름 *.tsv
이 별표와 모두 로 바뀝니다 .
$ mv *1.txt *.tsv
‘file1.txt’ -> ‘*.tsv’
$ ls
file2.txt *.tsv
당신이 대신 말했다 :
$ mkdir *.tsv
$ mv *.txt *.tsv
mv
명령으로 실행한다 :
argc = 3
argv[0] = mv
argv[1] = file1.txt
argv[1] = file2.txt
argv[2] = *.tsv
마찬가지로 *.tsv
지금이 디렉토리, 존재까지 파일의 끝이 움직였다.
이제 : some_command *.tsv
실제로 와일드 카드를 유지하려는 의도 와 같은 명령을 사용 하면 항상 와일드 카드를 인용해야합니다. 인용 부호를 사용하면 일치하는 항목이 있으면 와일드 카드가 확장되지 않습니다. 예를 들어 mkdir "*.tsv"
.
다음과 같은 경우 확장을 더 볼 수 있습니다.
$ ls
file1.txt file2.txt
$ mkdir *.txt
mkdir: cannot create directory ‘file1.txt’: File exists
mkdir: cannot create directory ‘file2.txt’: File exists
이제 mv
명령이 여러 파일에서 작동 할 수 있습니다. 그러나 둘 이상이 있으면 마지막 디렉토리가 대상 디렉토리 여야합니다. (선택적 -t TARGET_DIR
으로 적어도 GNU mv의 경우 옵션을 사용할 수 있습니다 .)
그래서 이것은 괜찮습니다 :
$ ls -F
b1.tsv b2.tsv f1.txt f2.txt f3.txt foo/
$ mv *.txt *.tsv foo
여기에 mv
호출됩니다 :
argc = 7
argv[0] = mv
argv[1] = b1.tsv
argv[2] = b2.tsv
argv[3] = f1.txt
argv[4] = f2.txt
argv[5] = f3.txt
argv[6] = foo
모든 파일은 디렉토리에있게 foo
됩니다.
당신의 링크에 관해서. mv
전혀 언급되지 않은 ( 댓글로) 하나를 제공 했지만 rename
. 더 많은 링크가 있으면 공유 할 수 있습니다. 이것을 주장하는 매뉴얼 페이지뿐만 아니라 표현됩니다.
나는 이것이 당신의 질문에 대답하지 않는다는 것을 알고 있지만, 당신이 당신의 해결책 루프와 비교하여 파일의 이름을 바꾸는 다른 방법을 찾고 find
있다면 왜 사용하지 않습니까? 이 명령을 여러 번 사용하여 큰 디렉토리의 파일 확장자를 수십만 개의 파일로 대체했습니다. 이것은 POSIX 호환 시스템에서 작동해야합니다.
find . -name "*.gappedPeak" -exec sh -c 'mv "$1" "${1%.gappedPeak}.bed"' _ {} \;
명령 분석 :
'
.
'=> '로 표시된 현재 디렉토리에서 시작하는 검색 경로. '
-name
=> 찾기 일치 이름 설정 (이 경우으로 끝나는 모든 파일.gappedPeak
)
-exec
=> 일치 할 때마다 다음 명령을 실행하십시오.
sh -c
=> 'exec'는 각 일치에 대해 독립적 인 셸 환경을 만듭니다.
mv "$1" "${1%.gappedPeak}.bed"
=> 현재 파일 이름 인mv
첫 번째 변수 ( $ 1 로 표시 )는 새 이름입니다. 여기에 하위 문자열 일치 및 삭제를 수행합니다. 첫 번째 var, $ 1을 다시 사용 하여 문자열에서%
삭제.gappedPeak
하십시오..bed
말은 바로 지금 남아있는 변수 연결해 으로, 새로운 생성, 파일 이름을.test#
.bed
test#.bed
밑줄은 $ 0 의 자리 표시 자입니다.
이 명령으로 찾은
{}
각 (*.gappedPeak
) 파일 이름으로 바뀌고find
명령의 $ 1이 됩니다sh
.
\;
-exec
명령 의 끝을 표시합니다 . 당신은 또한 사용할 수 있습니다';'
또는";"
.
예:
[user@before]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.gappedPeak
[user@after]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.bed
file.abc
-> blub.xyz
에 대한 또 다른 단순화 된 예입니다 .find . -name "file.abc" -exec sh -c 'mv "$1" "$(dirname $1)/blub.xyz"' _ {} \;
mv *.txt *.tsv
작동하지 않습니다. mv
한 번에 하나의 파일 이름 만 바꿀 수 있습니다. 설명을 잘못 이해했거나 잘못되었습니다.
mmv
그리고 rename
한 번에 여러 파일 이름을 바꿀 수 있습니다. 그러나 두 가지 버전이 rename
있습니다. 여기에 대해 많은 질문이 있어야합니다.
rename
아닌을 사용 mv
합니다.
mv *.txt *.tsv
mv
않습니다 (보통) 볼 *.txt
또는 *.tsv
쉘 - 확장 파일 이름을하지만. 이러한 와일드 카드로 확장되는 파일 수는 "무작위"입니다. 이것이 작동하는 유일한 상황은 이름 *.txt
을 가진 파일이 (문자 그대로) *.tsv
(따옴표없이 bash
옵션을 nullglob
설정하지 않아야 함 ) 이름의 파일이있는 경우 입니다.
foo.txt
와 하나의 이름이 baz.tsv
(가) mv *.txt *.tsv
기존 덮어 쓰게됩니다 .tsv
파일을 ...
당신은 예를 들어, asd.txt
그리고 qwe.txt
당신이 명령을 실행할 때 디렉토리에있는 파일 mv *.txt *.tsv
, 그것은라는 이름의 디렉토리에 두 파일을 이동하려고합니다 *.tsv
. 그러한 디렉토리가 없기 때문에 오류가 발생합니다.
고려해야 할 또 다른 옵션은 다음을 사용하는 것입니다.
cp -p *.txt *.tsv
rm -f *.txt
*.txt
파일을 복사합니다 .*.tsv
-p
*.txt
mv
파일이 다른 파티션에 있지 않으면 실제로 파일을 이동하지 않고 단순히 / directory / filename을 변경하는 것보다 느립니다 .