我只需要在所有嵌套目錄(包括 PWD)下將具有一個特定擴展名的檔案與使用“ globbing ”的 BASH 匹配。
- 我不需要將所有嵌套目錄下的所有檔案與 shell globbing匹配,但不需要在 PWD 中匹配。
- 我需要使用grep以外的命令來匹配檔案 搜索所有帶有檔案擴展名的目錄
- 我不需要只遞回地grep,而只需要在具有特定擴展名s(復數)的檔案中
set -o globstar; ls **/*.*對所有檔案都很好(不是我的問題)。ls **/*.phpPWD 中不匹配。set -o globstar; **/*.php回傳重復檔案。
grep -r --include=\*.php "find me" ./專門用于grep,而不是通配符(考慮這個問題)。似乎grep有--include=GLOB,因為使用通配符是不可能的。
從這個答案(這里),我相信可能沒有辦法使用通配符來做到這一點。
tl;博士
我需要:
- 全域運算式
- 匹配任何可以使用簡單 glob 的命令(
ls,sed,cp,cat,chown,rm, 等等) - 主要在 BASH 中,但其他 shell 會很有趣
- 在 PWD 和所有子目錄中遞回
- 對于具有特定擴展名的檔案
我僅將grep&ls用作示例,但我需要一個也適用于其他命令的全域運算式。
grep -r --include=GLOB不是一個 glob 運算式,比如cp; 這是特定于解決方案的解決方法,grep而不是解決方案。find不是 glob,但grep如果沒有這樣的 glob 運算式,它可能是非命令的解決方法。它需要|orwhile do;,等等。
例子
假設我有這些檔案,都包含“找到我”:
./file1.js
./file2.php
./inc/file3.js
./inc/file4.php
./inc.php/file5.js
./inc.php/file6.php
我只需要匹配一次/所有.php:
./file2.php
./inc/file4.php
./inc.php/file6.php
重復回傳:shopt -s globstar; ... **/*.php
這改變了問題;它沒有解決它。
重復:ls
在shopt -s globstar作為單個命令輸入之前...
ls **/*.php回傳:
inc/file4.php
inc.php/file5.js
inc.php/file6.php
- file2.php 不回傳。
shopt -s globstar作為單個命令輸入后...
ls **/*.php回傳:
file2.php
inc/file4.php
inc.php/file6.php
inc.php:
file5.js
file6.php
- inc.php/file6.php 回傳兩次。
重復:grep
在shopt -s globstar作為單個命令輸入之前...
grep -R "find me" **/*.php回傳:
inc/file4.php: find me
inc.php/file6.php: find me
- file2.php 不回傳。
shopt -s globstar作為單個命令輸入后...
grep -R "find me" **/*.php回傳:
file2.php: find me
inc/file4.php: find me
inc.php/file5.js: find me
inc.php/file6.php: find me
inc.php/file6.php: find me
- inc.php/file6.php 回傳兩次。
- 在看到從
ls輸出中看到的重復項后,我們知道原因了。
- 在看到從
當前解決方案:錯誤的誤用&&邏輯
grep -r "find me" *.php && grep -r "find me" */*.php
ls -l *.php && ls -l */*.php
- 請不!
I fail here && so I never happen
所需的解決方案:通過通配的單個命令
grep -r "find me" [GLOB]
ls -l [GLOB]
洞察來自grep
grep確實有--include標志,它實作了相同的結果,但使用特定于grep. ls沒有--include選項。這讓我相信沒有這樣的 glob 運算式,這就是為什么grep有這個標志。
uj5u.com熱心網友回復:
使用 bash,您可以先執行 ashopt -s globstar以啟用遞回匹配,然后該模式**/*.php將擴展到當前目錄樹中具有 .php 擴展名的所有檔案。
zsh 和 ksh93 也支持這種語法。其他將 glob 模式作為引數并對其進行自身擴展的命令(如您的grep --include)可能不會。
uj5u.com熱心網友回復:
使用 shell globing,只能通過/在 glob 末尾添加 a 來獲取目錄,但沒有辦法專門獲取檔案(zsh例外)
插圖:
使用給定的樹:
file.php
inc.php/include.php
lib/lib.php
假設 shell 支持非標準**glob:
**/*.php/擴展到inc.php/**/*.php擴展到file.php inc.php inc.php/include.php lib/lib.php對于 get
file.php inc.php/include.php lib/lib.php,您不能使用 glob。
=> 有了zsh它**/*.php(.)
標準解決方法(任何外殼,任何作業系統)
遞回獲取與給定標準glob匹配的檔案然后對它們應用命令的 POSIX 方法是使用find -type f -name ... -exec ...:
ls -l <all .php files>將會:
find . -type f -name '*.php' -exec ls -l {}
grep "finde me" <all .php files>將會:
find . -type f -name '*.php' -exec grep "finde me" {}
cp <all .php files> ~/destination/將會:
find . -type f -name '*.php' -type f -exec sh -c 'cp "$@" ~/destination/' _ {}
備注:這個有點棘手,因為您需要~/destination/在檔案引數之后,并且find's 的語法不允許find -exec ... {} ~/destination/
uj5u.com熱心網友回復:
建議不同的策略:
使用顯式命令在使用選項的選定檔案上find構建命令。bash-printf
檢查命令的正確性并運行。
1. 準備bash選定檔案的命令
find . -type f -name "*.php" -printf "cp %p ~/destination/ \n"
2.檢查輸出,正確的命令,正確的過濾器,測驗
cp ./file2.php ~/destination/
cp ./inc/file4.php ~/destination/
cp ./inc.php/file5.php ~/destination/
3. 執行準備好的find輸出
bash <<< $(find . -type f -name "*.php" -printf "cp %f ~/destination/ \n")
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/475847.html
