grep диапазон чисел в текстовом файле

Я понятия не имею, почему раздел не отображается на вашем рабочем столе Arch (графические интерфейсы IMO странные и ненадежные и часто содержат раздражающие жестко запрограммированные предположения 1 ), но если раздел виден операционной системе, например с помощью sudo fdisk -l или sudo blkid или sudo lsblk , тогда вы можете вручную смонтировать раздел в любом месте. Например:

sudo mkdir -p /windows-data
sudo mount -t ntfs -o ro /dev/sda2 /windows-data

Как всегда, вы можете настроить точные параметры монтирования (например, для uid, gid, perms) в соответствии с вашими потребностями.

Вы также можете вызвать автоматическое монтирование раздела, добавив строку в / etc / fstab , например:

/ dev / sda2 / windows-data ntfs uid = 1000, gid = 1000, noatime, allow_other 0 2

(это все в одной строке, а не в двух)

1 Если бы мне пришлось угадывать, я бы сказал, что рабочий стол Arch знает, что такое "HPFS / NTFS Раздел / exFAT есть и будет отображать его, но не знает, что такое «основные данные Microsoft», поэтому игнорирует его.

0
21.06.2018, 13:56
4 ответа
grep 201806{19..21} test

расширяется оболочкой до:

grep 20180619 20180620 20180621 test

Что grepпонимает как поиск 20180619внутри 3 файлов, 20180620, 20180621и test.

Если изменить на:

grep -e201806{19..21} test

Затем это расширяется до:

grep -e20180619 -e20180620 -e20180621 test

Что дает 3 eвыражения для grepдля поиска в test.

Или вы можете:

printf '%s\n' 201806{19..21} | grep -f - test

Когда мы передаем выражения в виде количества строк ввода вgrep(с некоторыми реализациями, вам может понадобиться /dev/stdinвместо-).

В частности, zshвы также можете сделать это:

numbers=({19..21} 25 31)
grep -E "201801(${(j:|:)numbers})" test

Где мы используем флаг расширения параметра (j:|:)для соединения элементов массива с|(расширенным оператором чередования регулярных выражений ), чтобы его можно было использовать в качестве ERE.

Или вы можете связать этот массив со скаляром регулярного выражения с помощью:

$ typeset -T re numbers '|'
$ numbers=({19..21} 25 31)
$ echo $re
19|20|21|25|31

В то время как регулярные выражения обычно не имеют возможности сопоставления диапазонов чисел, zshшаблоны (, которые с extendedglobфункционально эквивалентны регулярным выражениям )работают с оператором <x-y>(только для последовательностей десятичных цифр):

print -rl -- ${(M)${(f)"$(<test)"}:#*201806<19-21>*}
3
28.01.2020, 02:13

Да, grepпо умолчанию рассматривает только свой первый аргумент как регулярное выражение.

Это означает, что

grep {1..9} file

, который расширяется до

grep 1 2 3 4 5 6 7 8 9 file

будет вызывать grepс 1в качестве выражения для соответствия в других операндах, и ожидается, что эти другие операнды будут именами файлов.

Другая ваша команда:

grep 201806* test

Это попытается сопоставить 201806*как шаблон подстановки имени файла. У вас нет файлов, имена которых начинаются с 201806в текущем каталоге, поэтому оболочка zshне может развернуть шаблон и выдает сообщение об ошибке no matches found.

В других Bourne -подобных оболочках, если бы шаблон не соответствовал именам файлов, он остался бы нераскрытым и использовался бы как регулярное выражение с grep. Выражение 201806*, рассматриваемое как регулярное выражение, соответствует 20180, за которым следует ноль или более 6символов, например. 2018066666.

Вместо этого вы можете создать регулярное выражение, соответствующее вашему диапазону:

grep -E '201806(19|20|21)' test

или

grep -E '201806(19|2[01])' test

-Eнеобходимо, чтобы grepпонять|(чередование )в выражении (это чередование делает его расширенным регулярным выражением ).


Вы также можете создать регулярное выражение из раскрытия фигурной скобки:

set -- {19..21}
re=$( IFS='|'; printf '201806(%s)' "$*" )

grep -E "$re" test

Сначала будут установлены позиционные параметры $1, $2и $3.на желаемые номера в диапазоне. Затем переменная reбудет установлена ​​на 201806(%s), где printfзаменит %sэтими числами, разделенными |.

Вызов grepбудет использовать 201806(19|20|21)в качестве регулярного выражения.

6
28.01.2020, 02:13

строки без кавычек интерпретируются оболочкой до выполнения команды, в вашем случае испробованная вами команда будет расширена доgrep 20180619 20180620 20180621 test

$ echo grep 201806{19..21} test
grep 20180619 20180620 20180621 test

Одним из способов обхода является указание чередования регулярных выражений:

$ grep -E '201806(19|20|21)' test
20180619:
20180620:
20180621:

Вы можете построить числовой диапазон с помощью регулярных выражений, но это непросто. Подробнее см.https://www.regular-expressions.info/numericranges.html


Другой вариант — использоватьawk

$ awk -F: '$1>=20180619 && $1<=20180621' ip.txt
20180619:
20180620:
20180621:

Здесь мы разделяем строку на :и затем сравниваем первое поле $1с требуемым диапазоном

2
28.01.2020, 02:13
  1. POSIX оболочка (нетbash)с утилитами:

    seq 20180618 20180624 | grep -f - test
    
  2. numgrep:

    numgrep '/20180618..20180624/' < test
    
1
28.01.2020, 02:13

Теги

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