使用 mv 重命名多個文件以更改副檔名
我想重命名文件以更改其副檔名,有效地完成
mv *.txt *.tsv
但是當我這樣做時,我得到:
*.tsv 不是目錄
我覺得前 10 個Google熱門節目
mv
應該像這樣工作有點奇怪。
當您發出命令時:
mv *.txt *.tsv
如果有任何匹配的文件(包括目錄),假設 bash,shell會擴展萬用字元。文件列表被傳遞給程序,在這裡。如果未找到匹配項,則通過未擴展的版本。
mv
再說一遍:shell擴展了模式,而不是程序。
大量範例可能是最好的方法,所以我們開始吧:
範例 1:
$ 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
範例 2:
現在,如果您改為說:
$ 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
範例 3:
如果你改為說:
$ 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"
。範例 4:
如果您這樣做,可以進一步查看擴展,例如:
$ ls file1.txt file2.txt $ mkdir *.txt mkdir: cannot create directory ‘file1.txt’: File exists mkdir: cannot create directory ‘file2.txt’: File exists
範例 5:
現在:該
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’ 為每個匹配創建一個獨立的 shell 環境mv "$1" "${1%.gappedPeak}.bed"
=>mv
第一個變數(由**$1表示),即目前文件名,改為新名稱。在這裡我進行子字元串匹配並刪除;所以再次取第一個 var,$1**並用於從字元串%
中刪除。.gappedPeak
最後.bed
的 只是連接剩餘的變數,在下面的範例中,它現在是, 和,創建新的文件名。test*Number*``.bed``test*Number*.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