例如,我們有以權限編號 555 或 700 或 777 命名的檔案夾......我們如何獲取檔案名并根據檔案夾名稱更改所有具有權限的子檔案夾和檔案?因此,如果我們將其應用于檔案夾 555,則當前檔案夾和其中的所有內容都將擁有 555 的權限,我已經嘗試過
find . -name "[0-9][0-9][0-9]" -type d | xargs chmod -Rv [0-9][0-9][0-9]
但它只需要第一個檔案夾名稱并將其應用于我希望它處理每個檔案夾名稱(經許可命名)的所有內容,謝謝。
uj5u.com熱心網友回復:
不確定是否理解問題。
需要樣本輸入和樣本輸出才能理解。
建議以下解決方案:
dir_name="555"; chmod -R "$dir_name" $(find . -path "*$dir_name*")
解釋
dir_name="555"; :分配一個dir_name包含目錄名稱 555和chmod 權限值的變數555
$(find . -path "*$dir_name*"):列出當前目錄下的所有檔案555,它們的路徑中的某個位置。
chmod -R "$dir_name" : chmod 命令使用的值dir_name 555
uj5u.com熱心網友回復:
我會用這樣的東西。
find . -type d -name '???' -printf '%f\n' | xargs -I'{}' chmod -R '{}' '{}'
-type d-- 只查找目錄。-name ???-- 這將涵蓋名為 555、700、777 等的目錄printf '%f\n'-- 僅列印目錄的名稱。
為了真正安全,我會添加另一個選項(-maxdepth):
find . -maxdepth 1 -type d -name '???' -printf '%f\n' | xargs -I'{}' chmod -R '{}' '{}'
maxdepth 1-- 不要對子檔案夾進行任何搜索。
uj5u.com熱心網友回復:
我試過 find 。-name "[0-9][0-9][0-9]" -type d | xargs chmod -Rv [0-9][0-9][0-9] 但它只采用第一個檔案夾名稱并將其應用于我希望它分別處理每個檔案夾名稱(命名為許可)的所有內容
您的嘗試在幾個方面是錯誤的,其中包括:
該
[0-9][0-9][0-9]模式匹配包含非八進制數字字符的名稱。當
[0-9][0-9][0-9]shell 決議命令時,模式將被擴展。如果擴展成功,那么第一個匹配的名稱將給出應用的模式。如果擴展不成功,那么(默認情況下)模式本身將被傳遞給chmod,這將把它作為無效模式拒絕。默認情況下,該
xargs命令將采用盡可能多的輸入來形成一個命令的引數。因此,在您的示例命令中,如果find標識了檔案夾700、555、755,400那么xargs最終將執行如下操作:chmod -Rv <... expansion of [0-9][0-9][0-9] ...> 700 555 755 400即使模式擴展為空(可能在稍微不同的情況下發生),您也會得到與以前類似的結果:第一個目錄名稱將提供模式,而所有其他目錄名稱將更新為該模式。
這種變化應該做你想要的:
find . -name "[0-7][0-7][0-7]" -type d |
sed 's,^.*/\([^/]*\)$,\1\n\0,' |
xargs -r -l2 chmod -Rv
該sed命令采用由 發出的每個路徑find,提取基本名稱,并將其放在單獨的前一行。例如,如果其中一行find發出的是
./subdir/755
然后 sed 將其更改為
755
./subdir/755
. 也就是說,要應用的模式和應用它的目錄。
然后-l2選項xargs告訴它(最多)使用兩個輸入行來形成每個chmod命令,所以你最終會得到一系列形式的命令
chmod -Rv 755 ./subdir/755
The -r option to xargs is a nicety that tells it to avoid executing any commands at all if no lines are read from the standard input.
Addendum: the sed expression in more detail
[Note: I have slightly simplified the sed command given in the original version of this answer.]
The sed command ...
sed 's,^.*/\([^/]*\)$,\1\n\0,'
... processes each input line according to the given expression, a substitute command with comma (,) delimters.
- The target pattern is
^\(.*/\)\([^/]*\)$. This matches- a sequence starting at the beginning of the line (
^), - matching any number of any character
.*, - followed by a slash (
/) character, - followed by any number of any character other than slash (
[^/]*) - running to the end of the line (
$).
- a sequence starting at the beginning of the line (
- The part after the last slash is captured as a group.
- the replacement text is
- the contents of the first (only) capture group (
\1), followed by - a newline (
\n), followed by - the whole match (
\0), which will be the original line because the match is anchored to both the beginning and end of the line.
- the contents of the first (only) capture group (
sed will match each input line against the target pattern. Any line containing at least one slash will match, and every line emitted by the given find command will satisfy that criterion. The whole match (which will be the whole line) will be replaced by the given replacement, consisting of two lines -- one containing the tail of the original line following the last slash, and the other containing the whole original line.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/433639.html
