Shell
如何使用管道指定輸出文件名?
我正在使用 find 從目錄及其子目錄中返回文件列表:
find $directory -type f -name "*.epub"
然後我想使用一個需要指定輸入和輸出文件名的命令:
ebook-convert input.epub output.txt
我想將每個轉換
.epub
為.txt
輸出儲存在與輸入相同的目錄/子目錄中。簡單的管道不起作用。find $directory -type f -name "*.epub" | ebook-convert
我該怎麼做呢?
訣竅是不要創建然後迭代的文件列表(參見例如Why is looping over find’s output bad practice?)。
find "$directory" -type f -name '*.epub' -exec ebook-convert {} output.txt \;
*.epub
這將查找目錄中或目錄下名稱匹配的所有正常文件$directory
。對於每一個,ebook-convert
命令都以找到的文件的路徑名作為它的第一個參數和output.txt
第二個參數來執行。這顯然會覆蓋
output.txt
每個找到的文件,但以下將通過創建一個與原始文件同名的文件並-converted.txt
添加到名稱末尾(與原始文件位於同一目錄中)來解決此問題:find "$directory" -type f -name '*.epub' -exec ebook-convert {} {}-converted.txt \;
這可能不適用於所有實現,
find
因為它可能無法用找到的文件的路徑名替換第二個{}
(因為它與另一個字元串連接;但例如 GNUfind
處理它)。要解決這個問題:find "$directory" -type f -name '*.epub' -exec sh -c ' for pathname do ebook-convert "$pathname" "$pathname"-converted.txt done' sh {} +
使用支持globbing 模式的 shell,例如
bash
or :zsh``**
for pathname in "$directory"/**/*.epub; do ebook-convert "$pathname" "$pathname"-converted.txt done
(這需要
shopt -s globstar
inbash
並將處理任何匹配的名稱,而不僅僅是正常文件,除非您使用*.epub(.)
inzsh
或顯式-f
測試 inbash
)