实施例
for FILE in $DIR/*
do
if(<is last File>)
doSomethingSpecial($FILE)
else
doSomethingRegular($FILE)
fi
done
要求<is last file>
检查当前文件是否是数组中的最后一个文件?
是否有一个简单的内置检查,而不是自己检查数组的长度?
答案 0 :(得分:14)
要求检查当前文件是否是数组中的最后一个文件?
首先,您没有使用数组。如果你那么这很容易:
declare -a files
files=($DIR/*)
pos=$(( ${#files[*]} - 1 ))
last=${files[$pos]}
for FILE in "${files[@]}"
do
if [[ $FILE == $last ]]
then
echo "$FILE is the last"
break
else
echo "$FILE"
fi
done
答案 1 :(得分:8)
我知道无法告诉您正在处理for循环中列表的最后一个元素。但是你可以使用一个数组,遍历除最后一个元素之外的所有元素,然后处理循环外的最后一个元素:
files=($DIR/*)
for file in "${files[@]::${#files[@]}-1}" ; do
doSomethingRegular "$file"
done
doSomethingSpecial "${files[@]: -1:1}"
扩展${files[@]:offset:length}
会对offset
元素的所有元素进行求值,从length
开始(如果为空,则为空)。 ${#files[@]}-1
是数组中元素的数量减去1。
${files[@]: -1:1}
计算到最后一个元素 - 结尾为-1,长度为1.由于:-
的处理方式与: -
不同,所以空格是必需的。
答案 2 :(得分:4)
试试这个
LAST_FILE=""
for f in *
do
if [ ! -z $LAST_FILE ]
then
echo "Process file normally $LAST_FILE"
fi
LAST_FILE=$f
done
if [ ! -z $LAST_FILE ]
then
echo "Process file as last file $LAST_FILE"
fi
可生产
bash[1051]: ls
1 2 3 4
bash[1052]: sh ../last_file.sh
Process file normally 1
Process file normally 2
Process file normally 3
Process file as last file 4
答案 3 :(得分:3)
您可以使用find查找文件总数。 然后当你在循环计数到总数并执行你的任务时总数等于计数,即最后一个文件。
f=0
tot_files=`find . -iname '*.txt' | wc -l`
for FILE in $DIR/*
do
f=($f+1)
if [[ $f == $tot_files ]];then
carryout your task
fi
done
答案 4 :(得分:2)
什么使文件成为最后一个?它有什么特别之处吗?按名称排序时,它是名称最大的文件吗?
也许你可以向后取文件名。然后,它是您想要处理特殊而不是最后一个的第一个文件。弄清楚第一个是比做最后一个更容易的任务:
for file in $(ls -r1 $dir)
do
if [ ! $processedLast ]
then
doSomethingSpecial($file)
processedLast=1
else
doSomethingRegular($file)
fi
done
不需要数组。实际上,我喜欢chepner关于使用位置参数的答案。
答案 5 :(得分:1)
你可以滥用位置参数,因为它们的行为类似于数组, 但操作起来要容易一些。你应该保存旧的位置 参数,或在子shell中执行。
# Method 1: use a subshell. Slightly cleaner, but you can't always
# do this (for example, you may need to affect variables in the current
# shell
files=( $DIR/* )
(
set -- "${files[@]}"
until (( $# == 1 )); do
doSomethingRegular "$1"
shift
done
doSomethingSpecial "$1"
)
# Method 2: save the positional parameters. A bit uglier, but
# executes everything in the same shell.
files=( $DIR/* )
oldPP=( "$@" )
set -- "${files[@]}"
until (( $# == 1 )); do
doSomethingRegular "$1"
shift
done
doSomethingSpecial "$1"
set -- "${oldPP[@]}"
答案 6 :(得分:1)
基于@cdarke(https://stackoverflow.com/a/12298757/415523)当前得出的最高投票答案,如果查看一般数组值(而不是磁盘上的特定文件),循环代码如下:
declare -a array
declare -i length current
array=( a b c d e c )
length=${#array[@]}
current=0
for VALUE in "${array[@]}"; do
current=$((current + 1))
if [[ "$current" -eq "$length" ]]; then
echo "$VALUE is the last"
else
echo "$VALUE"
fi
done
这会产生输出:
a
b
c
d
e
c is the last
这可确保只有数组中的 last 项触发备用操作,并且如果数组中的任何其他项重复上一个值,则替代操作 not 呼吁更早的重复。
如果是特定目录中文件的路径数组,例如
array=( $DIR/* )
...它可能不那么令人担忧,因为同一目录中的单个文件名几乎肯定是唯一的(除非你有真正的奇数文件系统!)
答案 7 :(得分:0)
这是一个古老的问题 - 但是根据@GregReynolds的回答,如果命令仅在最后一次传递时的参数不同,请使用这个单行。单线爱好者的丑陋丑陋代码
( ff="" ; for f in * "" ; do [ -n "$ff" ] && echo $(${f:+false} && echo $ff alternate params here || echo normal params $ff ) ; ff=$f ; done )
normal params 1
normal params 2
normal params 3
4 alternate params here