[英]How to use find and exec to execute multiple commands
我有這樣的需求:
在目錄video
,我需要
find ./video -type f | while read myfile; do
tmp=`basename $myfile` #example.mp4
tmp="${tmp/.mp4/.html}" #example.html
cp index.html "$tmp"
sed -i '' "s#sceneFilePath:.*#sceneFilePath: \"$myfile\",#g" $tmp
#done;
這是我的目錄:
dir
|--- video
| |--- example.mp4
|--- index.html
|--- generateHtml.sh
generateHtml.sh
就像上面一樣。
這是它的作用:
在video
找到example.mp4
文件,然后cp index.html example.html
並在example.html
更改字符串。
它運作良好。
但是,對於.mp4
文件的某些路徑和名稱,現在有一些特殊字符,例如&
, ,
-
。 在這種情況下, while read
似乎沒有用。
我聽說過find -exec
可以處理所有特殊字符,但是在這種情況下我不知道如何使用它。
有關詳細討論,請參見使用查找 。
find ./video -type f -print0 | while IFS= read -r -d '' myfile; do
tmp=$(basename "$myfile") #example.mp4 -- consider also tmp=${myfile##*/}
tmp="${tmp%.mp4}.html" #example.html
sed "s#sceneFilePath:.*#sceneFilePath: \"$myfile\",#g" \
<index.html >"$tmp"
done
注意:
-print0
用於find
端, IFS= read -r -d ''
用於read
端; 這樣可以確保支持所有可能的文件名(包括帶有換行符的名稱,包括帶有前導或尾隨空格的名稱)。 .mp4
的第一個實例替換為.html
,而前一個替換已替換為將.mp4
去除文件名末尾並附加.html
替換。 basename
引用"$myfile"
。 這是原始代碼中最嚴重的直接錯誤,因為以前文件名可以拆分為basename
多個單獨參數。 $()
代替反引號。 這種現代的(並且是兼容POSIX的)命令替換語法可以很容易地嵌套,並且對於其中的反斜杠轉義具有更清晰的語義。 sed -i
是非標准且不可移植的(上述內容對MacOS有效,但對GNU無效); 可以跳過cp
並在線進行轉換。 如果您使用的是bash
4或更高版本,我不會在這里find
。 for
循環會簡單得多。 請注意,無需復制文件,然后就地編輯它; 只需將sed
命令的輸出重定向到所需文件即可。
for f in video/**/*.mp4; do
[ -f "$f" ] || continue
tmp=$(basename "$f" .mp4).html
sed "s#sceneFilePath:.*#sceneFilePath: \"$f\",#g" index.html > "$tmp"
done
如果您實際上不需要遞歸到video
子目錄,則只需for f in video/*.mp4; do
for f in video/*.mp4; do
,並且整個過程不僅在bash
早期版本中起作用,而且在shell和sed
都符合POSIX的環境中起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.