Как извлечь или проверить последнее поле из строки? - PullRequest
0 голосов
/ 18 февраля 2019

Я пишу bash-скрипт для проверки некоторых данных.Я создал переменную для хранения вывода оператора SQL:

$ declare -p data_ck
declare -- data_ck="2019-02-17  TRUE    2019-02-10  23"

Я предполагаю, что моя переменная data_ck на самом деле является просто строкой, а не массивом, который я могуразбирать на поля.Итак, я затем выяснил этот синтаксис: echo ${data_ck[@]:27:2}

, который возвращает «23» в этом случае.

Я также мог бы использовать: echo "${data_ck[@]: -2:2}"

Я хочуопределить, равен ли мой последний элемент, 23, 30. Я пробовал разные варианты этого оператора, но безуспешно:

If [ ${data_ck[@]:27:2} != 30 ]; then echo "missing dates"

, который возвращает: -bash: синтаксическая ошибка рядом с неожиданным токеном `then '

Я получаю тот же результат, используя этот метод:

If [ ${data_ck[@]:27:2} -ne 30 ]; then echo "missing dates" fi

Я только немного знаком со сценариями и не понимаю, что я делаю неправильно.Может кто-нибудь протянуть руку?Спасибо!

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Предполагая, что data_ck является скалярной переменной, а не массивом, основываясь на результате delcare -p data_ck, вы можете просто сказать:

data_ck="2019-02-17 TRUE 2019-02-10 23"
if [[ ${data_ck: -2:2} != 30 ]]; then
    echo "missing dates"
fi

Следующее все еще работает, но в основном излишне:

if [[ ${data_ck[@]: -2:2} != 30 ]]; then
    echo "missing dates"
fi

Как указывает @chepner, ${data_ck[@]} здесь оценивается как ${data_ck[0]} и эквивалентно $data_ck в контексте.

0 голосов
/ 19 февраля 2019
set -x
declare -- data_ck="2019-02-17  TRUE    2019-02-10  23"
last_field=${data_ck##*[[:space:]]}
[[ $last_field = 30 ]]

... правильно выдает:

+ [[ 23 = 30 ]]

..., что говорит нам, что ${data_ck##*[[:space:]]} успешно удалил все до последнего поля, что позволяет сравнить содержимое поля с 30 согласно вашей спецификации.

Он сделал это как расширение параметра , сопоставив и удалив самую длинную строку, заканчивающуюся пробелом.(*[[:space:]] - это шаблон в стиле глобуса , совпадающий с любой строкой, заканчивающейся пробелом; ${var##pattern} расширяется до содержимого $var с максимально длинным соответствием для pattern, удаленным с начала).

0 голосов
/ 19 февраля 2019

Я не могу видеть все варианты data_ck.Это может быть

data_ck=( 2019-02-17 TRUE 2019-02-10 23 )
data_ck=( 2019-02-17 FALSE 2019-02-10 23 )
data_ck=( 2019-02-17 TRUE 2019-02-10 301233 0 )
data_ck=( "2019-02-17 TRUE 2019-02-10 23" )

Значение FALSE и третий пример делает невозможным использование некоторого фиксированного смещения после преобразования массива в строку.Вы можете извлечь четвертое поле с помощью

if [ "${data_ck[@]:3:1}" = "23" ]; then echo "23 found"; fi
# or shorter
if [ "${data_ck[3]}" = "23" ]; then echo "23 found"; fi

РЕДАКТИРОВАТЬ: Когда data_ck является строкой, вам все равно нужно подумать, как лучше всего заполнить ваше поле.Некоторые возможности:

echo "${data_ck}" | sed 's/.* //'    # Get everything after last space
echo "${data_ck}" | sed -r 's/.* ([^ ]+) */\1/' # get last field in string ending with spaces
echo "${data_ck}" | cut -d" " -f4    # Get 4th field
echo "${data_ck}" | awk '{print $4}' # 4th field where 2 spaces count as 1 delimiter
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...