Что плохого в этом сравнении, что оно не позволяет правильно сравнивать значения? - PullRequest
0 голосов
/ 05 мая 2020

Я пытаюсь найти самую старую дату (в строковом формате) из списка элементов. Я не могу понять, почему сравнение не работает, что приводит к тому, что самая старая найденная дата всегда является временной самой старой датой, как показано здесь:

filedates=(20200110 20200120 20200219 20200220 20200420 20200422 20200110 20200120 20200219 20200220 20200420 20200422 20200219 20200220 20200420 20200422)

find_oldest_date (){
    arr=("$@")
    currentOldestDate=${arr[0]} # set a temporary oldest date
    echo "Temporary oldest date: "$currentOldestDate
    for date in "${arr[@]}"; do
     currentDate=$date
    if [[ "$currentDate" -lt "$currentOldestDate" ]]; then
      oldestDateFound=$currentDate
     else
      oldestDateFound=$currentOldestDate
     fi
    done
    echo "Oldest date found in directory: "$oldestDateFound
}
find_oldest_date "${filedates[@]}"

для сравнения, которое я также пробовал:

 if [[ "$currentDate" < "$currentOldestDate" ]]

Или только с одинарными скобками и двойными кавычками, или с двойными скобками без кавычек ...

Требуется передать дату файла в качестве параметра, а не использовать его напрямую

Ответы [ 4 ]

1 голос
/ 05 мая 2020

Вы никогда не изменяете значение currentOldestDate с его начального значения ${arr[0]}. В результате вы сообщаете дату последнего просмотра, которая меньше ${arr[0]}, но необязательно самая старая дата просмотра.

find_oldest_date (){
    arr=("$@")
    <b>oldestDateFound</b>=${arr[0]}
    echo "Temporary oldest date: "$<b>oldestDateFound</b>
    for date in "${arr[@]}"; do
     currentDate=$date
    if [[ "$currentDate" -lt "$<b>oldestDateFound</b>" ]]; then
      oldestDateFound=$currentDate
     <strike>else
      oldestDateFound=$currentOldestDate</strike>
     fi
    done
    echo "Oldest date found in directory: "$oldestDateFound
}

Вы можете упростить это до

find_oldest_date () {
  oldest=$1
  shift
  for current; do
    [[ $current -lt $oldest ]] && current=$oldest
  done
  echo "Oldest date found in directory: $oldest"
}
1 голос
/ 05 мая 2020

Обратите внимание, что вы можете просто отсортировать аргументы численно:

find_oldest_date() {
   printf "%s\n" "$@" | sort -n | head -n1
} 
0 голосов
/ 05 мая 2020

Упростите.

$: filedates=(20200110 20200120 20200219 20200220 20200420 20200422 20200110 20200120 20200219 20200220 20200420 20200422 20200219 20200220 2020020 20200422)
$: find_oldest_date (){ printf "%s\n" "$@" | sort | head -1; }
$: find_oldest_date "${filedates[@]}"
20200110

Также ... в вашем примере первый - самый старый, насколько я могу судить. Добавьте тестовое значение.

$: filedates=(20200110 20200120 20200219 20190220 20200420 20200422 20200110 20200120 20200219 20200220 20200420 20200422 20200219 20200220 2020020 20200422)
$: find_oldest_date "${filedates[@]}"
20190220

Для эффективности -

find_oldest_date() {
  local oldest="$1"; 
  for d in "$@"; do [[ "$d" < "$oldest" ]] && oldest="$d"; done;
  echo "$oldest"; 
}
0 голосов
/ 05 мая 2020

В вашем коде вы всегда сравниваете $currentDate (фактическая дата в списке, который вы просматриваете) с $currentOldestDate (который является всего лишь первым элементом массива, он не является «текущим»). Вы должны сравнить $currentDate с аккумулятором, который содержит самую старую найденную дату, и обновить при необходимости:

filedates=(20200110 20200120 20200219 20200220 20200420 20200422 20200110 20200120 20200219 20200220 20200420 20200422 20200219 20200220 20200420 20200422)

find_oldest_date (){
    arr=("$@")
    currentOldestDate="${arr[0]}" # set a temporary oldest date
    echo "Temporary oldest date: $currentOldestDate"
    for date in "${arr[@]}"; do
        if [[ "$date" -lt "$currentOldestDate" ]]; then
            currentOldestDate="$date"
        fi
    done
    echo "Oldest date found in directory: $currentOldestDate"
}
find_oldest_date "${filedates[@]}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...