Как извлечь некоторые значения, попадающие в диапазон

# ls -l | grep -e "-rw-r--r--"

Используйте -eдля grep, он выведет список всех файлов с нужным разрешением.

2
10.11.2021, 21:15
3 ответа

Используя прописные буквы -в качестве разделителей с awk, мы можем посмотреть на второе поле, чтобы определить, следует ли извлекать строку или нет:

$ awk -F '[[:upper:]]' '$2 >= 2400 && $2 <= 3100' file
T2662A
E3021K

На самом деле, поскольку использование поля, содержащего смесь цифр и не -цифр, в качестве числа преобразует поле в число, останавливаясь на первой не -цифре, достаточно обработать первую символ в строке как разделитель:

$ awk -F '^.' '$2 >= 2400 && $2 <= 3100' file
T2662A
E3021K

С sedнемного сложнее, так как этот инструмент, как известно, плохо справляется с арифметикой. Приведенная ниже команда просто включена в качестве забавного отвлечения.

Здесь мы сопоставляем три регулярных выражения с каждой строкой входных данных и печатаем строку, если есть совпадение. Первое выражение обрабатывает диапазон 2400 -2999, а второе выражение обрабатывает диапазон 3000 -3099. Мы тестируем 3100 отдельно с третьим выражением. В каждом тесте мы требуем, чтобы с каждой стороны числа встречался один символ верхнего регистра -.

$ sed -n \
    -e '/^[[:upper:]]2[4-9][0-9][0-9][[:upper:]]$/p' \
    -e '/^[[:upper:]]30[0-9][0-9][[:upper:]]$/p' \
    -e '/^[[:upper:]]3100[[:upper:]]$/p' file
T2662A
E3021K

Немного более длинный скрипт редактирования, который более эффективно выполняет тесты:

$ sed \
    -e '/^[[:upper:]]2[4-9][0-9][0-9][[:upper:]]$/b' \
    -e '/^[[:upper:]]30[0-9][0-9][[:upper:]]$/b' \
    -e '/^[[:upper:]]3100[[:upper:]]$/b' \
    -e d file
T2662A
E3021K

Команда bбез аргументов выполняет ветвление скрипта до конца, где неявная операция печати выводит текущую строку. Последняя команда dвыполняется для строк, не содержащих совпадений. Это гарантирует, что строки, имеющие совпадения, не проверяются больше, чем необходимо.

4
11.11.2021, 06:08

Использование Raku (, ранее известного как Perl _6)

raku -ne '.put if.grep(/ (<digit>+) / && {2400 <= $0 <= 3100});'

ИЛИ

raku -ne '.put if.grep(/ $<loc> = [<digit>+] / && {2400 <= $<loc> <= 3100} );'

Пример ввода:

S1437T
H1266Y
T2662A
E1397A
E626K
S1538T
E3021K

Пример вывода:

T2662A
E3021K

Кратко, Raku вызывается из командной строки с -neфлагами (без -автопечати, построчно -чтением ). Раку grepиспользуется для поиска соответствия<digit>+(одной -или -больше цифр ), и если они найдены, значения проверяются в блоке {...}, чтобы увидеть, соответствуют ли они диапазону условие. Обратите внимание, как весь диапазон можно проверить за один раз с помощью блока условия {2400 <= $0 <= 3100}.

Второй пример с $<loc>показывает реализацию Раку с именем -захватывает . См. URL-адрес ниже для получения дополнительной информации.

Наконец, Raku предлагает фактический Rangeкласс объектов, поэтому вышеприведенный код можно записать следующим образом с оператором ~~smartmatch и 2400..3100диапазоном. Ниже приводится тот же образец вывода, что и выше :

.
raku -ne '.put if.grep(/ $<loc> = [<digit>+] / && { $<loc> ~~ 2400..3100 } );'

https://docs.raku.org/syntax/Named%20captures
https://docs.raku.org/type/Range
https://raku.org

1
11.11.2021, 08:54

В Python есть функция сравнения по цепочке, которая соответствует цели.

python3 <<\eof
with open('file') as f:
  for l in f:
    n = int(l[1:-2])
    if 2400 <= n <= 3100:
      print(l,end="")
eof
T2662A
E3021K

Также можно создать объект диапазона и сравнить его с Таким образом, мы можем заменить цепное сравнение if следующим:

if n in range(2400,3100+1):

мы можем использовать команду perl grep для поиск существования номера.

perl -lne 'my $n = s/\D//gr;
  print if grep(/^$n$/,2400..3100);
' file

Здесь мы используем GNU sed для предварительной обработки данных для команды GNU dc, которая затем проверяет принадлежность к диапазону, сравнивая произведение (число -нижний предел )x (верхний предел -число )>= 0, чтобы претендовать на печать.

sed -Ee '
  h;s/.(.*)./\1/
  x;s/.*/[&]/;G;
  s/\n/ /
' file |
dc -e "
[q]sq [p]sp
[2400-r3100r-*0!>p]su
[?z0=q dlux c z0=?]s?
l?x
"

Здесь в этом методе мы сначала сортируем числовые значения, начиная со 2-го столбца и далее

sort -k1.2n file |
awk '{n=0+substr($0,2)}
n < 2400 {next}
n > 3100 {exit}
1'
0
11.11.2021, 23:29

Теги

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