如何列舉目錄中的所有文件文件,並按模式排除。
例如:所有 *.pdf 排除 *_book.pdf。我嘗試這樣:
for $PDF in $(ls *.pdf | grep -v *_book.pdf);
do
echo "File $PDF"
done
這是個好辦法嗎?還有其他方法嗎?用過的如果聲明或其他。
答案1
另外,在循環中宣告的變數for
不應帶有美元符號。美元符號插值變數的值;所以$PDF
讀作“名稱為”的變數的當前值PDF
。
for PDF in *.pdf
do
case $PDF in
*_book.pdf) continue;;
esac
echo "File $PDF"
done
這種文法讓一些初學者感到害怕,但對於這樣的事情case
我更喜歡它。if
但如果您願意,您可以使用
if [[ $PDF =~ _book\.pdf$ ]]; then
continue
fi
或簡寫
[[ $PDF =~ _book\.pdf$ ]] && continue
case
還有一個額外的好處是它可以移植到 POSIXsh
甚至是古老的原始 Bourne sh
。
請注意, in 中的模式case
是一個 glob,而 while[[ $variable =~ regex ]]
使用正規表示式(因此不應有*
before _book
)。
答案2
使用shopt -s extglob
(這可能是系統上的預設設置,否則進行設定),您可以使用擴展匹配,這包括否定匹配模式:
# Directry contents
>ls -1
1_book_not.pdf
1_book.pdf
1.pdf
1.txt
# With negative match
>ls -1 !(*_book).pdf
1_book_not.pdf
1.pdf
答案3
您的for
表達式中有一個輕微的語法錯誤。請嘗試以下方法:
for PDF in $(ls *.pdf | grep -v *_book.pdf);
do
echo "File $PDF"
done
這看起來效果不錯。
答案4
另一個選擇是使用find
:
find . -maxdepth 1 -name '*.pdf' ! -name '*_book.pdf'
例如,考慮包含以下四個檔案的目錄:
$ ls
a_book.pdf book.txt nook.pdf not_book1.pdf
現在,運行我們的命令:
$ find . -maxdepth 1 -name '*.pdf' ! -name '*_book.pdf'
./not_book1.pdf
./nook.pdf
怎麼運作的
find .
告訴 find 在目前目錄中開始搜尋。-maxdepth 1
告訴 find 跳過子目錄。-name '*.pdf'
告訴 find 找出名稱以 if 結尾的檔案.pdf
。! -name '*_book.pdf'
告訴 find 從輸出排除任何名稱以_book.pdf
.