嘗試使用前瞻(因此awk而不是sed)進行正則運算式替換,洗掉所有點,保存最后一個點以保留擴展名eg: (my.big.file.avi > my-big-file.avi)。這是我的小 bash 腳本:
#!/bin/bash
shopt -s globstar nullglob dotglob
for file in ./**/*.{mpg,mpeg,mkv,avi,mp4}; do
newFile=$(printf $file | awk '{gsub(/\.(?=.*?\.)/"-");}1')
#ffmpeg -i "$newFile" -vcodec copy -acodec aac "${newFile%.*}_AAC.mp4"
printf "${file} ---> ${newFile}\n"
done
這給了我一個regular expression compile failed (missing operand)錯誤...
我看不到。有人可以指出我的錯誤嗎?
uj5u.com熱心網友回復:
解決這個問題的任何部分都不需要 awk 或正則運算式;引數擴展就足夠了。
#!/bin/bash
shopt -s globstar nullglob dotglob
for file in ./**/*.{mpg,mpeg,mkv,avi,mp4}; do
dirname=${file%/*} # we don't want to change the directory name
filename=${file##*/} # so split out just the filename
[[ $filename = *.*.* ]] || continue # no compound extension? do nothing
file_start=${filename%.*} # content up to last dot
file_ext=${filename##*.} # content after last dot
newFile=${dirname}/${file_start//./-}.${file_ext} # combine the two
# okay, got what we need, now we can work with it
#ffmpeg -i "$newFile" -vcodec copy -acodec aac "${newFile%.*}_AAC.mp4"
printf '%s ---> %s\n' "$file" "$newFile"
done
但是如果你想使用正則運算式:
#!/bin/bash
shopt -s globstar nullglob dotglob
for file in ./**/*.{mpg,mpeg,mkv,avi,mp4}; do
[[ $file =~ ^(.*)/([^/] )[.]([^/.] )$ ]] || continue
dirname=${BASH_REMATCH[1]}
file_start=${BASH_REMATCH[2]}
file_ext=${BASH_REMATCH[3]}
newFile=${dirname}/${file_start//./-}.${file_ext}
printf '%s ---> %s\n' "$file" "$newFile"
done
uj5u.com熱心網友回復:
還有一個遠沒有查爾斯那么優雅的替代品,但也許也能完成這項作業......
echo my.big.file.avi | sed -E 's/\./-/g;s/-([^-] )$/.\1/'
my-big-file.avi
uj5u.com熱心網友回復:
GNUAWK有限地支持前瞻,即$行\>尾和字尾。你的任務,即
洗掉所有點保存最后一個以保留擴展名,例如:
(my.big.file.avi > my-big-file.avi)
可以使用 GNUAWK的處理字串的函式來完成,我將按如下方式進行,讓file.txt內容為
my.big.file.avi
i-do-not-need-change.mp3
name-without-dot
然后
awk '{match($0,/[.][^.]*$/); print gensub(/[.]/,"-","g",substr($0,1,RSTART-1)) substr($0,RSTART)}' file.txt
輸出
my-big-file.avi
i-do-not-need-change.mp3
name-without-dot
注意:我添加了 2 個測驗用例。說明:首先用于match查找文字點 ( [.]) 后跟零個或多個 ( *) 非點 ( [^.]) 和行尾 ( $)。這將設定RSTART為行中最后一個點的位置。然后我substr用來獲取最后一個點之前的部分和最后一個點和后續字符的部分。在第一部分我用 - 替換所有點,在第二部分我什么都不做,然后將它們和print. 如果您想了解有關我使用的函式的更多資訊,請閱讀String Functions 檔案。
(在 GNU Awk 5.0.1 中測驗)
請記住,某些檔案的擴展名有 2 個點,例如file.tar.gz,我的解決方案沒有考慮到這一點。
(因此
awk與否sed)
可怕的警告:sed在圖靈完整。衍生:它可以做任何其他圖靈語言可以完成的事情。話雖如此,它確實意味著您應該使用它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/348050.html
