考虑到我们有很多名字像DSC_20170506_170809.JPEG. 为了重命名照片以使其遵循模式Paris_20170506_170809.JPEG,我编写了以下完美运行的脚本。
for file in *.JPEG; do mv ${file} ${file/DSC/Paris}; done
Run Code Online (Sandbox Code Playgroud)
我的问题是,我们如何使用while循环而不是循环来编写此脚本for?
在while这里使用循环没有任何问题。你只需要正确地做:
set -- *.jpeg
while (($#)); do
mv -- "${1}" "${1/DSC/Paris}"
shift
done
Run Code Online (Sandbox Code Playgroud)
while上面的循环与for循环一样可靠(它适用于任何文件名),而后者 - 在许多情况下 - 最适合使用的工具,前者是一个有效的替代1有其用途(例如以上可以一次处理三个文件或只处理一定数量的参数等)。
所有这些命令(set,while..do..done和shift)都记录在 shell 手册中,它们的名称是不言自明的......
set -- *.jpeg
# set the positional arguments, i.e. whatever that *.jpeg glob expands to
while (($#)); do
# execute the 'do...' as long as the 'while condition' returns a zero exit status
# the condition here being (($#)) which is arithmetic evaluation - the return
# status is 0 if the arithmetic value of the expression is non-zero; since $#
# holds the number of positional parameters then 'while (($#)); do' means run the
# commands as long as there are positional parameters (i.e. file names)
mv -- "${1}" "${1/DSC/Paris}"
# this renames the current file in the list
shift
# this actually takes a parameter - if it's missing it defaults to '1' so it's
# the same as writing 'shift 1' - it effectively removes $1 (the first positional
# argument) from the list so $2 becomes $1, $3 becomes $2 and so on...
done
Run Code Online (Sandbox Code Playgroud)
1:它不是文本处理工具的替代品,所以永远不要使用while循环来处理文本。