Bash 解决方案
这也是 Bash 解决方案可能有用的地方。以下测试扩展(max 4 chars + .
)设置为extsz
在脚本中。如果找到扩展名,脚本会删除文件名中的空格,然后将文件从旧名称移动到新名称(实际移动在下面注释)。它依赖于参数扩展/子串替换操作空格和文件名:
#!/bin/bash
declare -i extsz=-5 # extension w/i last 4 chars
## trim leading/trailing whitespace
function trimws {
[ -z "$1" ] && return 1
local strln="${#1}"
[ "$strln" -lt 2 ] && return 1
local trimstr=$1
trimstr="${trimstr#"${trimstr%%[![:space:]]*}"}" # remove leading whitespace characters
trimstr="${trimstr%"${trimstr##*[![:space:]]}"}" # remove trailing whitespace characters
printf "%s" "$trimstr"
return 0
}
## for each filename read from stdin
while read -r ffname || test -n "$ffname" ; do
## test for extension and set 'ext' if present
for ((i=$extsz; i<0; i++)); do
[ "${ffname:(i):1}" == '.' ] && { ext=${ffname:(i)}; break; }
done
## if extension, move the file to name w/o trailing space w/orig extension
if [ -n "$ext" ]; then
fname="${ffname%.*}" # separate filename from extension
fnwosp="$(trimws "$fname")" # trim whitespace from filename
printf " renaming : '%s' -> '%s'\n" "$ffname" "${fnwosp}${ext}"
#mv "$ffname" "${fnwosp}${ext}" # commented for testing
else
## if no extension, just trim whitespace and move
printf " renaming : '%s' -> '%s'\n" "$ffname" "$(trimws "$ffname")"
# mv "$ffname" "$(trimws "$ffname")"
fi
unset ext # unset 'ext' for next iteration
done
exit 0
Input
$ cat dat/wfname.txt
QDN34 Unit5 mark-up - Judy .pdf
QDN34 Unit7 mark-up - Judy .pdf
file with two character ext .ai
file with dot. trailing space and no ext
file with no ext
Output
$ bash fixfilenames.sh <dat/wfname.txt
renaming : 'QDN34 Unit5 mark-up - Judy .pdf' -> 'QDN34 Unit5 mark-up - Judy.pdf'
renaming : 'QDN34 Unit7 mark-up - Judy .pdf' -> 'QDN34 Unit7 mark-up - Judy.pdf'
renaming : 'file with two character ext .ai' -> 'file with two character ext.ai'
renaming : 'file with dot. trailing space and no ext' -> 'file with dot. trailing space and no ext'
renaming : 'file with no ext' -> 'file with no ext'
Note:当读自stdin
,shell 将去除不带扩展名的文件名的尾随空格。
读取文件名作为参数
为了说明如何从不带扩展名的文件名末尾删除空格,有必要引用并读取文件名作为参数。如果这就是您所需要的,这里有一个替代品。无论如何,将文件名作为参数读取而不是从标准输入中批量读取可能更有意义:
#!/bin/bash
declare -i extsz=-5 # extension w/i last 4 chars
## trim leading/trailing whitespace
function trimws {
[ -z "$1" ] && return 1
local strln="${#1}"
[ "$strln" -lt 2 ] && return 1
local trimstr=$1
trimstr="${trimstr#"${trimstr%%[![:space:]]*}"}" # remove leading whitespace characters
trimstr="${trimstr%"${trimstr##*[![:space:]]}"}" # remove trailing whitespace characters
printf "%s" "$trimstr"
return 0
}
## test at least 1 command line argument
[ $# -gt 0 ] || {
printf "error: insufficient input. usage: %s <filename>\n" "${0##*/}"
exit 1
}
## for each of the filenames give as arguments
for ffname in "$@"; do
## test for extension and set 'ext' if present
for ((i=$extsz; i<0; i++)); do
[ "${ffname:(i):1}" == '.' ] && { ext=${ffname:(i)}; break; }
done
## if extension, move the file to name w/o trailing space w/orig extension
if [ -n "$ext" ]; then
fname="${ffname%.*}" # separate filename from extension
fnwosp="$(trimws "$fname")" # trim whitespace from filename
printf " renaming : '%s' -> '%s'\n" "$ffname" "${fnwosp}${ext}"
#mv "$ffname" "${fnwosp}${ext}" # commented for testing
else
## if no extension, just trim whitespace and move
printf " renaming : '%s' -> '%s'\n" "$ffname" "$(trimws "$ffname")"
# mv "$ffname" "$(trimws "$ffname")"
fi
unset ext
done
exit 0
Example
$ bash fixfilenames.sh 'testfile w end space '
renaming : 'testfile w end space ' -> 'testfile w end space'
$ bash fixfilenames.sh 'file with two character ext .ai'
renaming : 'file with two character ext .ai' -> 'file with two character ext.ai'