尝试用前瞻性(因此是awk
而不是sed
(替换正则表达式,该前瞻性删除所有点,保存最后一个点以保留扩展eg: (my.big.file.avi > my-big-file.avi)
。这是我的小狂欢脚本:
#!/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)
错误。。。
我看不见。有人能指出我的错误吗?
解决这个问题的任何部分都不需要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 ---> %sn' "$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 ---> %sn' "$file" "$newFile"
done
GNUAWK
对lookahead的支持有限,即$
表示行尾,>
表示字尾。您的任务,即
删除所有点,保留最后一个点以保留扩展,例如:
(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
连接起来。如果你想了解更多关于我使用的函数的信息,请阅读字符串函数文档。
(在GNU Awk 5.0.1中测试(
请记住,有些文件的扩展名为2个点,例如file.tar.gz
,我的解决方案没有考虑到这一点。
(因此
awk
而非sed
(
可怕的警告:sed
是图灵完备的。Ramiftion:它可以做任何其他图灵语言可以完成的事情。话虽如此,它确实意味着你应该使用它
awk中的两种详细方法:
[m/g/n]awk 'BEGIN { OFS = "-"
FS = "[.]"
} ($NF="."$NF)
&&
sub(/-./,".")'
对
[m/g/n]awk 'sub(/.[^.]+$/,"