Shell

如何使用管道指定輸出文件名?

  • August 19, 2019

我正在使用 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,例如bashor :zsh``**

for pathname in "$directory"/**/*.epub; do
   ebook-convert "$pathname" "$pathname"-converted.txt
done

(這需要shopt -s globstarinbash並將處理任何匹配的名稱,而不僅僅是正常文件,除非您使用*.epub(.)inzsh或顯式-f測試 in bash

引用自:https://unix.stackexchange.com/questions/536231