21

for FILE in $DIR/* 
do
  if(<is last File>)
    doSomethingSpecial($FILE)
  else
    doSomethingRegular($FILE)
  fi
done

<is last file>現在のファイルが配列の最後のファイルであるかどうかを確認するには、何を呼び出す必要がありますか?

自分で配列の長さをチェックせずに簡単な組み込みチェックはありますか?

4

8 に答える 8

20

現在のファイルが配列の最後のファイルであるかどうかを確認するには、何を呼び出す必要がありますか?

まず、配列を使用していません。もしそうなら、それは簡単でしょう:

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 
于 2012-09-06T11:09:19.180 に答える
10

forループでリストの最後の要素を処理していることを知る方法がわかりません。ただし、配列を使用して、最後の要素を除くすべてを反復処理してから、ループの外側で最後の要素を処理することもできます。

files=($DIR/*)
for file in "${files[@]::${#files[@]}-1}" ; do
    doSomethingRegular "$file"
done
doSomethingSpecial "${files[@]: -1:1}"

展開は、要素の開始(または空の場合は開始)の${files[@]:offset:length}すべての要素に評価されます。配列内の要素の数から1を引いたものです。offsetlength${#files[@]}-1

${files[@]: -1:1}最後の要素に評価されます-最後から-1、長さ1。スペースは、:-とは異なる方法で処理されるため、必要: -です。

于 2012-09-06T11:00:25.277 に答える
5

これを試して

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
于 2012-09-06T11:04:36.627 に答える
2

ファイルを最後のものにするのは何ですか? それについて何か特別なことはありますか?名前でソートしたときに最大の名前のファイルですか?

ファイル名をにすることもできます。次に、それは特別に扱いたい最初のファイルであり、最後ではありません。最初のものを理解することは、最後のものを行うよりもはるかに簡単な作業です:

for file in $(ls -r1 $dir)
do
    if [ ! $processedLast ] 
    then
        doSomethingSpecial($file)
        processedLast=1
    else
        doSomethingRegular($file)
    fi
done

配列は必要ありません。実際、位置パラメータの使用に関するchepnerの回答が気に入っています。

于 2013-07-22T17:30:23.017 に答える
2

位置パラメータは配列と同様に機能するため、乱用できますが、操作が少し簡単です。古い位置パラメータを保存するか、サブシェルで実行する必要があります。 

# 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[@]}"
于 2012-09-06T12:17:12.770 に答える
1

これは古い質問ですが、@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

于 2016-08-22T18:07:23.490 に答える