如何在bash中采用特定值?

时间:2019-02-27 10:53:13

标签: bash unix

我有一个看起来不连续的日期列表

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

我将其转换为数组 data_list =($ data_list)

然后我想要将两个特定日期之间的日期保存在变量中。也就是说,我想要2017041420170517之间的日期。

类似的东西:

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 :(得分:1)

用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

答案 1 :(得分:0)

如果日期已经排序,则可以使用循环来查找范围的开始和结束的索引,而不是使用参数扩展来提取它们:

#!/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}

答案 2 :(得分:0)

以下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

获取示例数据。

答案 3 :(得分:0)

像这样传递数组可能不是很有效,因此您可能决定使用全局变量(尽管这有其自身的问题)。

#!/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