簡體   English   中英

如何使用find和exec執行多個命令

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM