假设我有一个名为 的子目录sub
。然后我想对该目录中扩展名为“txt”的所有文件进行操作。我想要类似的东西
for f in sub/*.txt
do
enscript -b "" -o {$f basename excluding .txt}.ps sub/{$f basename excluding .txt}.txt
ps2pdf {$f basename excluding .txt}.ps {$f basename excluding .txt}.pdf
done
sub
因此,如果表单的目录中只有一个文件*.txt
,例如sub/foo.txt
,脚本应扩展为
enscript -b "" -o foo.ps sub/foo.txt
ps2pdf foo.ps foo.pdf
我通常更喜欢便携式解决方案,但了解不同的做事方式总是很有趣。所以非便携式也可以,请说明您的解决方案是便携式还是非便携式。另外,标题可能不是最好的,所以请随意修改。
编辑:我意识到所写的示例不太有意义,因为它foo.txt
位于sub
目录中,因此sub/foo.txt
需要传递到enscript
.我还将 -penscript
选项更改为更标准的-o
选项。
答案1
POSIX shell(例如,bash、dash、ksh 等)接受${var%suffix}
可用于从变量值中删除尾部部分的构造。例如,如果path="sub/file.txt"
,则${path%.txt}
扩展为sub/file
。
有一个对称构造可以删除前缀:${var#prefix}
。前缀可以是一个模式。将#
最长的匹配前缀加倍。例如, if path=sub/dir/file.txt
, then${path##*/}
扩展为file.txt
(并${path#*/}
扩展为dir/file.txt
)。后缀 和 也是如此%
。
因此,在您的情况下,您可以这样写(请注意,您不能将前缀剥离和后缀剥离合并到单个扩展中,至少不能仅使用 POSIX 构造):
for f in sub/*.txt; do
base=${f%.txt}
base=${base##*/}
enscript -b "" -o "$base.ps" "$f"
ps2pdf "$base.ps" "$base.pdf"
done
或者,GNU
基本名称命令接受可选的第二个参数,它是要删除的文件扩展名。例如,如果$f
是file.txt
,则$(basename $f .txt)
扩展为
file
。
但请注意,这basename
会删除除最后一个组件之外的所有路径信息,因此如果您只想删除扩展名,则必须将其放回去(请参阅
目录名命令)。
答案2
可移植的方法是使用 和 剥离扩展名${f%.*}
和目录${f##*/}
(或使用basename
)。
在zsh中,您可以申请各种变换到参数扩展, 包括历史修改器例如r
剥离一个扩展名和t
剥离目录部分。
for x in sub/*.txt; do
enscript -b "" -o ${x:t:r}.ps $x
ps2pdf ${x:t:r}.ps ${x:t:r}.pdf
done
您可以将历史修改器应用到全局模式以及。
for x in sub/*.txt(:r:t); do
enscript -b "" -o $x.ps sub/$x.txt
ps2pdf $x.ps $x.pdf
done