Объединив пробел и собрав все ответы вместе, а также взглянув на справочную страницу grep (man grep
), мы видим два основных типа регулярных выражений :Basic Regex и Extended Regex.
Согласно man grep:
Basic vs Extended Regular Expressions
In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, +, {, \|, (,and ).
Другими словами, вы можете захватывать группы с помощью одного grep, используя escape-последовательность ()
, например grep \(....\)
, или если вы используете grep -E
или egrep
, вам не нужно экранировать круглые скобки:egrep '(....)'
К sed применяются те же правила. Простой sed понимает основные регулярные выражения, поэтому вам нужно экранировать для захвата групп:sed 's/\(....\)\(...\)/\2/'
или вы можете включить расширенную поддержку регулярных выражений в sed
с помощью переключателя -E
или -r
(в зависимости от реализации sed):sed -E 's/(...)(...)/\2/'
В результате все приведенные ниже команды действительны:
$ echo "INBOUND_PATH|/tmp" | grep '^\(INBOUND_PATH\)|\(.*\)$';echo $?
INBOUND_PATH|/tmp
0
$ echo "INBOUND_PATH|/tmp" | egrep '(INBOUND_PATH)\|(.*)$';echo $?
INBOUND_PATH|/tmp
0
$ echo "INBOUND_PATH|/tmp" | sed 's/^\(INBOUND_PATH\)|\(.*$\)/\2/'
/tmp
$ echo "INBOUND_PATH|/tmp" | sed -E 's/(INBOUND_PATH)\|(.*)$/\2/'
/tmp
Обратите внимание на противоположную обработку специальных символов в разных регулярных выражениях.
Например, см. обработку символа трубы |
в приведенных выше командах:
В базовом регулярном выражении (BRE):
Вам не нужно экранировать символ трубы, чтобы соответствовать буквальному символу трубы.
Экранирующий символ вертикальной черты в BRE будет рассматриваться как оператор ИЛИ (, который случайно сработает в вашем случае ).
Аналогично, в BRE вам не нужно экранировать круглые скобки ( )
, чтобы соответствовать буквальным скобкам, но вам нужно экранировать круглые скобки, чтобы захватить группу.
В расширенном регулярном выражении (ERE):
Вам нужно экранировать символ трубы, чтобы сопоставляться буквально, поскольку по умолчанию в ERE символ трубы обрабатывается как оператор ИЛИ (, противоположная обработка по сравнению с BRE)
Точно так же в ERE вам нужно экранировать круглые скобки, чтобы соответствовать буквальному скобки (
, так как по умолчанию скобки в ERE используются для захвата групп.
Самый простой способ — использовать -S
с ls
для сортировки содержимого каталога по размеру. Файлы по-прежнему сгруппированы по каталогам, что может быть не совсем то, что вам нужно:
ls -RaltrS --block-size=M /*
Такой подход здесь может не подойти; возможно, all_files.txt
— это старый файл или он был сгенерирован на другом компьютере. По-прежнему можно сортировать имена файлов по размеру файла. Для типичного файла строка вывода, созданная ls -Raltr --block-size=M
(, обратите внимание, что --block-size
начинается с двух дефисов вместо одного ), выглядит следующим образом:
-rw-rw-r-- 1 owner group 1M Apr 16 05:37 file.txt
Используйте sort
с-h
(для -удобочитаемых чисел, таких как 1M ), и с -k 5
, чтобы указать, что размеры файлов указаны в пятом столбце (, разделенном пробелом )текста:
sort -k 5 -h /home/root/all_files.txt
Сортировка вывода ls -Raltr --block-size=M /*
, хранящегося в /home/root/all_files.txt
, может быть запутанной из-за дополнительных строк, в которых не указаны размеры файлов, поэтому сначала используйте grep
, чтобы получить только нужные строки:
grep '^-' /home/root/all_files.txt | sort -k 5 -h
Здесь grep '^-'
отбрасывает строки, которые не начинаются с дефиса (, например, строки, начинающиеся с d
для каталога или l
для ссылки ).
Этот ответ работает с инструментами GNU на Xubuntu 16.04. Он не тестировался на системах MacOS или BSD.
Чтобы отсортировать все обычные файлы в текущем каталоге или в нем по размеру, оболочка zsh
предоставляет удобный **
шаблон подстановки, который соответствует /
в путях (, т.е. «рекурсивно вниз в подкаталоги )Это также позволяет квалифицировать шаблон так, чтобы вы, например, получали совпадения только с обычными файлами, а результаты сортировались в соответствии с размером этих файлов.
В оболочке zsh
этот шаблон будет выглядеть как
**/*(.OL)
Это вернет все обычные файлы (.
), упорядоченные в обратном(O
)порядке размера(L
).
Чтобы получить список только файлов, используйте
printf '%s\n' **/*(.OL)
Чтобы получить ls
«длинный список», используйте
ls -fl **/*(.OL)
(опция -f
запрещает ls
выполнять собственную сортировку файлов ).
Если zsh
не является вашей обычной оболочкой, вы все равно можете использовать эти команды, предполагая, что zsh
установлен в вашей системе:
zsh -c 'ls -fl **/*(.OL)'
Очевидно, вы могли бы также добавить --block-size=M
к этому, если вы используете GNU ls
.
Если вас интересуют только десять самых больших файлов, используйте шаблон
**/*(.OL[1,10])
вместо этого.