Сценарий Bash не работает при использовании оператора case для принятия решения

Учитывая этот файл:

cat file
lat,lon,fhr
33.90000,-76.50000,0
34.20000,-77.00000,6
34.20000,-77.50000,12

затем

awk -F, '
    function interpolate(lat1, lon1, t1, lat2, lon2, t2,      i) {
        for (i = 1; i <= (t2 - t1); i++) {
            printf "%.5f,%.5f,%d\n",
                lat1 + i * (lat2 - lat1) / (t2 - t1),
                lon1 + i * (lon2 - lon1) / (t2 - t1),
                t1   + i
        }
    }
    NR <= 2 {print}
    NR >= 3 {interpolate(lat, lon, t, $1, $2, $3)}
    {lat = $1; lon = $2; t = $3}
' file

lat,lon,fhr
33.90000,-76.50000,0
33.95000,-76.58333,1
34.00000,-76.66667,2
34.05000,-76.75000,3
34.10000,-76.83333,4
34.15000,-76.91667,5
34.20000,-77.00000,6
34.20000,-77.08333,7
34.20000,-77.16667,8
34.20000,-77.25000,9
34.20000,-77.33333,10
34.20000,-77.41667,11
34.20000,-77.50000,12
1
03.01.2021, 22:46
2 ответа

Во входных файлах есть символы ^M (cr )перед символом новой строки unix (lf ). Поэтому ваше поле f7 не то, что ожидается.

Пропустите файл через :dos2unix < oldfile > newfile

или :tr -d '\015' < старый файл > новый файл

И попробуйте еще раз.

Убедитесь также, что:

  • все входные строки имеют 7 аргументов (пустые или нет, т.е. имеют 6 запятых):awk -F',' '(NF != 7) { print "line: " NR " has " NF " arguments : " $0 }' /home/opc/3A-Lab/schedule.csv
  • добавьте строку по умолчанию для вашего случая, чтобы уведомить, какие строки не соответствуют ни одному из случаев: *) printf "Something is wrong: We have a line with an unexpected f7='%s'\n" "$f7" ;;#перед esac.
  • удалить последнее эхо :оно будет отображаться всегда, что бы ни делал while.или просто измените его, чтобы сказать:echo "End of the script."
  • и в строке с часами есть лишние пустые аргументы :заменить at now + "$f6" " " "hours"наat now + "$f6" hours

Таким образом, сценарий становится:

#!/bin/bash
filename='/home/opc/3A-Lab/schedule.csv'

i=0
while IFS=, read -r f1 f2 f3 f4 f5 f6 f7; do
    i=$(( i + 1 ))
    if [ "$i" = "1" ]; then printf "Bypass first line\n" ; continue ; fi
    if [ -z "$f1" ]; then printf "Bypass line: %s, empty field f1\n" "$i" ; continue ; fi
    case "$f7" in
    NOT_S)
            printf "/home/opc/3A-Lab/3ALab.sh %s start\n" "$f5" | at  now
            printf "/home/opc/3A-Lab/3ALab.sh %s stop\n"  "$f5" | at  now + "$f6" hours
            printf "scheduled start and stop for line: %s\n" "$i"
            ;;
    YES)
            printf "line %s: YES : Already Scheduled\n" "%i"
            ;;
    "")     printf "Warning: I see an empty f7... for line: %s =  '%s,%s,%s,%s,%s,%s,%s'\n" "$i" "$f1" "$f2" "$f3" "$f4" "$f5" "$f6" "$f7"
            ;;
    *)
            printf "Something is wrong: line %s: we see f7='%s'\n No action taken.\n" "$i" "$f7"
            ;;
    esac
done < $filename

printf "End of the Script.\n"

Меня также озадачивает, почему вы не хотите ничего делать с первой встреченной строкой НЕ _S (, т.е. где i=1 )... Но у вас, вероятно, есть свои причины.

edit1 :заменил echo на printf везде, хорошая привычка брать (printf переносим, ​​echo нет. )edit2 :изменил сценарий после комментария об обходе заголовка и комментариев (и причины $i)

2
18.03.2021, 22:38

Как было объяснено в другом месте , строки вашего файла завершаются окончанием CRLF в стиле Windows -. Это означает, что ваше последнее поле всегда заканчивается символом CR, поэтому ваши литералы NOT_Sи YESникогда не могут совпадать.

Вы можете либо передать файл через конвертер, либо, что проще, просто игнорировать конечные символы в конце последнего поля:

case "$f7" in
    NOT_S*)... ;;
    YES*)... ;;
esac
1
18.03.2021, 22:38

Теги

Похожие вопросы