Bash:複数の変数の1つだけが同じであることを確認してください。

Bash:複数の変数の1つだけが同じであることを確認してください。

私は読む時間において「and」の形式を正しく指定しようとしています。最後の値(時間、分、または秒)以前と複数の値がある場合にのみ「and」をエコーする方法を見つけようとします(2つの値が必要です。つまり、2日と5日)。分または2日12時間5分)

正しい構文がわかりません。 H、M、Sのいずれかの値が0より大きい場合、$ DAnd = "and"です。これも数時間ずつ繰り返されるため、MとSだけが0より大きい値があれば「$HAnd="and」になります。数分でSが0より大きいが確認するので簡単です。

多くのコードを書かずにどうやってこれを達成できますか?

私の現在のスクリプト:

#!/bin/bash
TIME1="08/15/2018 10:30:41"
TIME2="08/30/2018 8:34:40"
SEC1=`date +%s -d "${TIME1}"`
SEC2=`date +%s -d "${TIME2}"`
DIFF=`expr ${SEC2} - ${SEC1}`
CONVERTTIME()
{
  local T=$1
  local D=$((T/60/60/24))
  local H=$((T/60/60%24))
  local M=$((T/60%60))
  local S=$((T%60))
  if [[ $D > 0 ]]; then
    [[ ($H = 0 || $M = 0 || $S = 0) && ($H = 0 && $M = 0 && $S = 0) ]] && DComma="" || DComma=","
    #The problem
    [[ ($H > 0 || $M > 0 || $S > 0) && ($H = 0 || $M = 0 || $S = 0) ]] && DAnd="" || DAnd="and "
    [[ $D = 1 ]] && echo -n "$D day$DComma " || echo -n "$D days$DComma $DAnd"

  fi
  if [[ $H > 0 ]]; then
    [[ ($M = 0 || $S = 0) && ($M = 0 && $S = 0) ]] && HComma="" || HComma=","
    #The problem
    [[ ($M > 0 || $S > 0) && ($M = 0 || $S = 0) ]] && HAnd="" || HAnd="and "
    [[ $H = 1 ]] && echo -n "$H hour$HComma $HAnd" || echo -n "$H hours$HComma $HAnd"
  fi
  if [[ $M > 0 ]]; then
    [[ $S = 0 ]] && MComma="" || MComma=", and "
    [[ $M = 1 ]] && echo -n "$M minute$MComma" || echo -n "$M minutes$MComma"
  fi
  if [[ $S > 0 ]]; then
    [[ $S = 0 ]] && echo -n "$S second" || echo -n "$S seconds"
  fi
  # If no difference in time:
  [[ $D = 0 && $H = 0 && $M = 0 && $S = 0 ]] && echo -n "0 seconds"
  echo
}
echo
echo "TIME DIFFERENCE: $(CONVERTTIME $DIFF)"
echo

ベストアンサー1

のように書く

seconds2text() {     
    local diff=$1
    local words=()
    if (( diff == 0 )); then
        words=("0 seconds")
    else
        local s=$((diff % 60))
        local m=$((diff / 60 % 60))
        local h=$((diff / 60 / 60 % 24))
        local d=$((diff / 60 / 60 / 24))

        (( d > 0 )) && { unit=day;    (( d > 1 )) && unit+=s; words+=("$d $unit"); };
        (( h > 0 )) && { unit=hour;   (( h > 1 )) && unit+=s; words+=("$h $unit"); }
        (( m > 0 )) && { unit=minute; (( m > 1 )) && unit+=s; words+=("$m $unit"); }
        (( s > 0 )) && { unit=second; (( s > 1 )) && unit+=s; words+=("$s $unit"); }
        (( ${#words[@]} > 1 )) && words[-1]="and ${words[-1]}"
    fi
    local IFS=,
    local text="${words[*]}"
    text=${text/,and/ and}
    echo "${text//,/, }"
}

それから

$ for d in 0 1 61 3600 3601 3660 3661 86400 86401 86460 86461 90000 90001 90060 90061 180122; do seconds2text $d; done
0 seconds
1 second
1 minute and 1 second
1 hour
1 hour and 1 second
1 hour and 1 minute
1 hour, 1 minute and 1 second
1 day
1 day and 1 second
1 day and 1 minute
1 day, 1 minute and 1 second
1 day and 1 hour
1 day, 1 hour and 1 second
1 day, 1 hour and 1 minute
1 day, 1 hour, 1 minute and 1 second
2 days, 2 hours, 2 minutes and 2 seconds

メモ:

  • [[ $x > 0 ]]そしてやって[[ $x = 0 ]]いるひも比較してみて、いいえ数字比較する。代わりに((x > 0))andを使用してください((x == 0))$ここでは必要ありません)。
  • 変数をすべて大文字にする習慣を捨ててください。皮のために残してください。ある日、あなたはPATH=something執筆を終え、なぜあなたの台本が壊れたのか疑問に思うでしょう。

おすすめ記事