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

У меня есть список непоследовательных дат, который выглядит как

data_list="20170410 20170411 20170412 20170414 20170415 20170416 20170417  20170419 20170420  20170422 20170423 24 20170425 20170516 20170517 20170518 20170519 20170520"

Я преобразую его в массив data_list = ($ data_list)

И затем я хочу, чтобы даты между двумя конкретными датамисохранено в переменной.То есть мне нужны даты между 20170414 и 20170517.

Что-то вроде:

new_variable=x[between 20170414 and 20170517]
echo $new_variable
20170414 20170415 20170416 20170417  20170419 20170420  20170422 20170423 24 20170425 20170516 20170517

Знаете ли вы, как это сделать?Я новичок в bash, поэтому извините, если задаю наивный вопрос.

Ответы [ 4 ]

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

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

#!/bin/bash

data_list="20170410 20170411 20170412 20170414 20170415 20170416
           20170417 20170419 20170420 20170422 20170423 24
           20170425 20170516 20170517 20170518 20170519 20170520"
data_list=( $data_list )

# usage: between lo hi list
between(){
    lo=$1; shift
    hi=$1; shift
    while [[ $# -gt 0 ]]; do
        if [[ $lo < $1 && $1 < $hi ]]; then
            echo $1
        fi
    done
}

new_variable=$(between 20170414 20170517 "${data_list[@]}")

echo $new_variable
0 голосов
/ 27 февраля 2019

Если даты уже отсортированы, вы можете использовать циклы для поиска индексов начала и конца диапазона, а затем использовать расширение параметров для их извлечения:

#!/bin/bash
data_string='20170410 20170411 20170412 20170414 20170415 20170416 20170417  20170419 20170420  20170422 20170423 24 20170425 20170516 20170517 20170518 20170519 20170520'
data=($data_string)

for (( i=0 ; data[i] < 20170414 ; i++ )) ; do : ; done
for (( j=${#data[@]}-1; data[j] > 20170517 ; j-- )) ; do : ; done

echo ${data[@]:i:j-i+1}
0 голосов
/ 27 февраля 2019

Следующая функция bash распечатает числа между нижней и верхней границами (обе включительно):

between() {
  min=$1
  max=$2
  shift 2
  for date; do
    (( date >= min && date <= max )) && echo "$date"
  done | paste -sd' '
}

Ваш формат даты позволяет нам интерпретировать даты как числа.Вы можете использовать функцию как

between 20170414 20170517 "${arrayOfDates[@]}"

, которая будет печатать

20170414 20170415 20170416 20170417 20170419 20170420 20170422 20170423 20170425 20170516 20170517

для данных вашего примера.

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

Обман с некоторым awk:

$ new_list=$(echo $data_list | awk 'BEGIN{RS=ORS=" "}$0>=20170414 && $0<=20170517')
$ echo $new_list
20170414 20170415 20170416 20170417 20170419 20170420 20170422 20170423 20170425 20170516 20170517

Объяснил немного:

echo $data_list |              # outputing the variable to awk 
awk 'BEGIN{
    RS=ORS=" "                 # separate records by a single space
}
$0>=20170414 && $0<=20170517'  # output lines between given values
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...