我遇到了與所問問題相同的問題 重命名缺少檔案副檔名的音樂文件 我發現@Gilles 提供的腳本非常有教育意義,但不幸的是它沒有按我預期的方式運作。我正在尋找的是一個腳本,它可以為所有子目錄、所有層級、「/path/to/music/directory/」下面的所有音樂檔案新增檔案副檔名,而無需擴展名。建議的命令列參數
/path/to/music/directory/{**/,}*
讓腳本遍歷「/path/to/music/directory/」以下一級子目錄中的所有文件,但不遍歷該子目錄下的所有文件。我應該使用什麼命令列參數來遍歷「directory/」以下各級的所有檔案?
也將不勝感激指向文件的指針
{**/,}*
部分。
順便說一句,對於那些對原始答案感興趣的人。我發現更改行後腳本效果更好
file -i "$@" |
到
file --mime-type "$@" |
(如果我有特權級別,我會在原始答案中將此作為評論給出)
答案1
我認為你只需要啟動 bashglobstar
選項,因為預設情況下它不是活動的烏班圖,如下所述。
這個表達式/path/to/music/directory/{**/,}*
包含兩個擴展結構:一個大括號擴展和一個路徑名擴展。
支撐擴張
用一個例子最好解釋大括號擴展:
$ printf '%s\n' before-{a,bb,1,22}-after
before-a-after
before-bb-after
before-1-after
before-22-after
(我在這裡和下面使用了printf '%s\n' item1 item2 etc..
類似於echo
但在新行上列印每個元素的命令)
您會看到大括號中的每個逗號分隔的元素都會產生一個展開的元素。
原始範例包含在大括號中的元素**/
和一個空元素,擴展為
$ printf '%s\n' /path/to/music/directory/{**/,}*
/path/to/music/directory/**/*
/path/to/music/directory/*
戒指球星
現在轉向 bash glob **
,它在bash 手冊頁,都與 shell 選項 相關globstar
,意思如下:
路徑名擴展上下文中使用的模式 ** 將匹配檔案以及零個或多個目錄和子目錄。
這個 shell 選項不是積極的Ubuntu 預設:
$ shopt globstar
globstar off
您可以使用以下命令來啟動它
shopt -s globstar
(用於shopt -u globstar
停用它)。
如果我們有以下目錄結構:
$ find first/ | sort
first/
first/aaa
first/second
first/second/bbb01
first/second/bbb02
first/second/third
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3
我們可以進行以下擴充:
$ printf '%s\n' first/**/a*
first/aaa
$ printf '%s\n' first/**/b*
first/second/bbb01
first/second/bbb02
$ printf '%s\n' first/**/c*
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3
所以你可以看到它**
能夠擴展到不只是一個路徑名元素。
答案2
我會做這樣的事情
#! /bin/bash
[[ -d "$1" ]] || { echo "$1 not a directory, exiting..."; exit 1; }
find "$1" -type f | while read F; do
# do what you want with the "$F"
done
exit 0
然後透過呼叫腳本./my_script <directory>