Поиск строки в txt адресов домов с диапазонами номеров путем передачи точного номера и названия улиц

Если вы используете Bash, вы можете включить histverify, а затем вызывать команды с помощью !, за которым следует номер команды в истории:

shopt -s histverify

Другой интересный подход заключается в использованииfc:

fc 200

загрузит 200-ю команду в вашей истории в ваш редактор. Затем вы можете отредактировать команду по своему усмотрению, и она будет выполнена, когда вы выйдете из редактора.

Другие оболочки, такие как Zsh, имеют аналогичные функции.

Подробности см. в главе о взаимодействии с историей в руководстве Bash .

1
09.05.2021, 03:06
2 ответа
#! /bin/bash

civic="$1"
street="$2"

if [ "$((civic%2))" = 1 ]; then
   exclude=" even "
else
   exclude=" odd "
fi

</path/to/addresses.txt grep "$street" \
   | grep -v "$exclude" \
   | awk -F '[ -]' -v civic="$civic" '
      {if ($1 !~ /^[0123456789]*$/ || $2 !~ /^[0123456789]*$/) print
       else if (civic>=$1 && civic<=$2) print}
     '

Процедура:

  1. Проверьте, является ли число нечетным или четным, и соответствующим образом подготовьте строку исключения.
  2. Первый grepвыбирает строки, соответствующие улице. Все строки соответствуют пустой строке, поэтому если не указать улицу, на этом шаге все строки будут совпадать.
  3. Второй grepисключает записи, описанные как «нечетные» или «четные», используя строку исключения из первого шага.
  4. awkразделяет каждую строку, используя пробелы и -в качестве разделителей. Если какое-либо из двух первых полей не является полностью числовым, диапазон не указывается и строка печатается. В противном случае, по-видимому, два первых поля определяют диапазон; Затем число проверяется на соответствие диапазону, и строка печатается, если она находится в пределах диапазона.
1
28.07.2021, 11:34

С awkи оберткой bash. Сохраните его как script.shи сделайте исполняемым.

#!/bin/bash

filename="data.txt"

n="$1"       # save number from argument list
shift        # remove number from argument list
s="$@"       # save remaining argument list
s="${s:=.*}" # set regex.* as default if street is missing

awk -v number="$n" -v street="$s" '
BEGIN{
  FS="-| "   # use field separator "-" or one space to split current row
}

$0 ~ street{
  # current row contains street

  if( $1 ~ /^[0-9]+$/ && $2 ~ /^[0-9]+$/ ){
    # current row starts with a range

    if( number >= $1 && number <= $2 ){
      # number is in expected range

      if ( $3 == "odd" || $3 == "even" ){
        # string "even" or "odd" found

        if ( $3 == "odd" && number ~ /[13579]$/ ){
          # odd
          print
        }

        if ( $3 == "even" && number ~ /[24680]$/ ){
          # even
          print
        }
      } else {
        # neither "even" or "odd" found
        print
      }
    }
    # finished with current row
    next
  }
  # match but no range found in current row
  print
}
' "$filename"
1
28.07.2021, 11:34

Теги

Похожие вопросы