我正在将doc
文件转换为在 Linux 上txt
使用catdoc
。为了保持与输出文件相同的文件名,我使用参数扩展替换.doc
扩展名。.txt
但有许多以.DOC
.如何使.doc
不${filename%.doc}.txt
区分大小写,同时保留文件名本身的大写字母?我无法使用,${filename%.*}.txt
因为有些文件的文件名中有点
我当前的代码:
find "${COMPANYPATH}" -iname '*.doc' | while read -r file; do
echo "${file}"
filename=$(basename "${file}")
path="${file%/*}/"
mkdir -p "${OUTPUTPATH}/DOC/${path#$COMPANYPATH/}"
catdoc "${file}" >> "${OUTPUTPATH}/DOC/${path#$COMPANYPATH}${filename%.doc}.txt"
done
输入
/home/user/test/2218-0/test.doc
/home/user/test/2218-0/Test2.DOC
预期产出
/home/user/output/test/DOC/2218-0/test.txt
/home/user/output/test/DOC/2218-0/Test2.txt
没有重复的文件。
答案1
我不认为你可以在 Bash 中使模式匹配${filename%.doc}
不区分大小写。你可以做到zsh, with ${filename%(#i).doc}
(需要setopt extendedglob
启用)或ksh93
with ${filename%~(i:.doc)}
. Bashnocasematch
没有帮助,它只能工作case
和[[ .. ]]
构建。
在任何 POSIX shell 中,始终存在使用 显式列出大写和小写字符的解决方法${filename%.[dD][oO][cC]}
。或者只是用 删除最后三个字符${filename%.???}
,知道find
只会给你正确的字符。
然后再次${filename%.*}
应该只删除最短的匹配部分,所以这也应该不是问题。 (%%
将删除最长的。)
兹什:
% setopt extendedglob
% filename=foo.bar.DoC
% echo ${filename%.(#i)doc}.txt
foo.bar.txt
嘘/猛击:
$ filename=foo.bar.DoC
$ echo "${filename%.[dD][oO][cC]}.txt"
foo.bar.txt
$ echo "${filename%.*}.txt"
foo.bar.txt
答案2
你不知道。只需完全删除扩展即可:
find "${COMPANYPATH}" -iname '*.doc' | while read -r file; do
echo "${file}"
filename=$(basename "${file}")
name="${file%.*}"
path="${file%/*}"
noComPath="${path#$COMPANYPATH/}"
mkdir -p "${OUTPUTPATH}/DOC/$noComPath"
catdoc "${file}" >> "${OUTPUTPATH}/DOC/$noComPath/$name.txt"
done
该表达式name="${file%.*}"
会将变量设置name
为文件名,并.
删除从最后到结尾的任何内容。如果有很多.
,则仅删除最后一个:
$ foo=file.foo.bar.DoC
$ echo "${foo%.*}"
file.foo.bar
这是一个更强大的版本,可以处理任意文件名(例如,如果文件名包含换行符,您将失败):
LC_ALL=C find "${COMPANYPATH}" -iname '*.doc' -type f -print0 |
while IFS= read -r -d '' file; do
printf>&2 'Processing "%s"\n' "${file}"
basename="${file##*/}"
dirname="${file%/*}"
rootname="${basename%.*}"
targetdir=${OUTPUTPATH}/DOC/${dirname#"${COMPANYPATH}/"}
mkdir -p -- "${targetdir}" &&
catdoc -- "${file}" >> "${targetdir}/${rootname}.txt"
done