3

Каков наилучший подход для преобразования строки, содержащей диапазон чисел, в сами числа? Этот формат используется, например, при определении диапазона страниц для печати. Я определяю, я хочу напечатать эти страницы "11-14,17,20". Теперь мне нужно написать скрипт bash, который изменит эту строку на массив чисел: 11, 12, 13, 14, 17, 20

Он должен уметь работать со строкой, которая содержит числа (даже с большим количеством цифр), а также с ',' и '-'.

5 ответов5

3

Вот решение с использованием awk:

#!/bin/bash

pages="11-14,17,20"

echo $pages | awk 'BEGIN { RS=","; FS="-"; ORS="" }
  NR > 1  { print "," }
  NF > 1  { for (i=$1; i<$2; ++i) { print i "," } print $2; next }
          { print $1 }'

Это приводит к следующему выводу:

11,12,13,14,17,20

3

Это делает это в Perl:

echo 11-14,17,20 | perl -pe 's/(\d+)-(\d+)/join(",",$1..$2)/eg'

Выход:

11,12,13,14,17,20
2

Просто bash:

expand_ranges() {
  local IFS=,
  set -- $1
  for range; do
    case $range in 
      *-*) for (( i=${range%-*}; i<=${range#*-}; i++ )); do echo $i; done ;;
      *)   echo $range ;;
    esac
  done
}
numbers=( $(expand_ranges 11-14,17,20) )

Для вашего запрошенного вывода: IFS=,; echo ${numbers[*]}

0

Если у вас есть jot из вашей системы

Пример использования jot и sed: (не забывайте о символе перевода строки в строке замены!):

$echo 1-2,3,6-9| sed 's/,/\
/g'|sed -E '/-/s/([0-9]+)-([0-9]+)/- \1 \2/g;s/^([0-9]+)$/- \1 \1/g'| xargs -L 1 jot | rs -t -C,
1,2,3,6,7,8,9

Если вы echo jot вместо "jot" (и удалите вызов rs ), вы должны увидеть следующий вывод:

jot - 1 2
jot - 3 3
jot - 6 9
0

Это похожий на шутку способ делать вещи (за исключением того факта, что bash не любит ленивые списки, поэтому мы должны установить верхнюю границу для максимального числа страниц; здесь я выбрал 10000)

pages="11-14,17,20"; for ((i=1;i<10000;i++)); do echo -n $i, ; done | cut -d , -f $pages

Для страниц вы указываете диапазон страниц, как в другом посте. Цикл for генерирует список номеров страниц. Из них команда cut выбирает те, которые вы хотите.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .