Bash Script: Проблема с переменными из CSV-файла

Bash Script: Проблема с переменными из CSV-файла

У меня возникла небольшая проблема с получением переменных из CSV-файла на моей машине Linux и использованием их в if. У меня есть следующий CSV-файл:

Name;Age
Marc;18
Joseph;10

Я пытаюсь получить эту информацию из моего csv для использования в функции:

Мой bash-код:

#!/bin/ksh

while IFS=";" read -r c_1 c_2 

do
  echo "Name : $c_1"
  echo "Age : $c_2"
   
if [ $c_2 == "18" ]
then
    echo "$c_1 can drive"
fi

done < <(tail -n +2 teste_input.csv)

После запуска кода я получаю:

Name : Marc
Age : 18
Name : Joseph
Age : 10

Я ожидал:

Name : Marc
Age : 18
Marc can drive
Name : Joseph
Age : 10

Я уже много чего перепробовал, но безуспешно. Я могу использовать c_1и c_2как входные данные для некоторых функций без проблем. Проблема только в том, что я пытаюсь выполнять математические операции.

Если я сделаю:

s=$c_2+1
d=$((${c_2}+1))

он возвращает:

+1
+1")syntax error: invalid arithmetic operator (error token is "

Та же проблема при использовании d=$(("${c_2}+1")).

Что мне нужно изменить, чтобы он заработал? Использование #!/bin/ksh, #!/bin/shили #!/bin/bashдает мне тот же результат.

Спасибо за вашу помощь :)

решение1

Первая проблема в том, что вы используете текстовый файл Windows. В вашем csv есть окончания строк в стиле Windows ( \r\n). Это можно исправить с помощью:

dos2unix teste_input.csv

Или, если у вас он не dos2unixустановлен, просто выполните:

sed -i 's/\r//g' teste_input.csv

Это заставит ваш код выдавать тот результат, который вы ожидаете. Почти:

$ foo.sh teste_input.fixed.csv 
Name : Marc
Age : 18
$c_1 can drive
Name : Joseph
Age : 10

Это $c_1происходит из-за одинарных кавычек в этой строке:

echo '$c_1 can drive'

Переменные не раскрываются внутри одинарных кавычек, поэтому вы видите $c_1, а не значение переменной. Вам нужно:

echo "$c_1 can drive"

Следующая проблема в том, что ==это для сравнения строк, а не арифметики. Здесь это сработает, но если вы хотите сравнить числовые значения, вам нужно -eq:

if [ $c_2 -eq "18" ]

Однако, основываясь на вашем выводе «can drive», я подозреваю, что вы хотите проверить, равно ли значение переменной или больше 18, поэтому вы бы использовали -ge:

 if [ $c_2 -ge "18" ]

Наконец, вам нужно выбрать одну оболочку для использования. kshне то же самое, что bashи , что не то же самое, что и sh. Хотя у них очень похожий синтаксис, он не идентичен, и некоторые вещи будут работать по-разному в зависимости от того, что вы используете. Например, shне поддерживает <(command).

Что касается арифметики, которую вы пробовали, вам просто нужно правильно использовать синтаксис, вам нужно использовать «арифметический контекст». s=$c_2+1это простое присваивание переменной. Это установка значения переменной $sв значение $c_2с помощьюнить +1добавлен:

$ c_2=10
$ s=$c_2+1
$ echo "$s"
10+1

Ваш второй пример d=$((${c_2}+1))работает, потому что (( ))задает арифметический контекст:

$ c_2=10
$ d=$((${c_2}+1))
$ echo "$d"
11

Вы получили синтаксическую ошибку из-за окончаний строк Windows:

$ c_2=10$'\r'
$ d=$((${c_2}+1))
+1")syntax error: invalid arithmetic operator (error token is "

Так что это исчезнет, ​​если вы исправите файл, как я описал в начале.

Связанный контент