Grep первая самая длинная линия
grep -Em1 "^.{$(wc -L <file.txt)}\$" file.txt
Команда необычно трудна для чтения без практики, потому что она смешивает синтаксис оболочки и регулярных выражений.
Для объяснения я сначала буду использовать упрощенный псевдокод. Строки, начинающиеся с ##, не запускаются в оболочке.
Этот упрощенный код использует имя файла F и оставляет для удобства чтения кавычки и части регулярных выражений.
Как это работает
Команда состоит из двух частей: grep- и wcвызова:
## grep "^.{$( wc -L F )}$" F
wcИспользуется в расширении процесса, $( ... )так оно выполняется до grep. Он рассчитывает длину самой длинной строки. Синтаксис расширения оболочки смешивается с синтаксисом шаблона регулярного выражения в некоторой путанице, поэтому я разложу расширение процесса:
## wc -L F
42
## grep "^.{42}$" F
Здесь расширение процесса было заменено на возвращаемое значение, создавая используемую grepкомандную строку. Теперь мы можем более легко прочитать регулярное выражение: оно точно соответствует от начала ( ^) до конца ( $) строки. Выражение между ними соответствует любому символу, кроме новой строки, повторяется 42 раза. В совокупности это строки, состоящие ровно из 42 символов.
Теперь вернемся к реальным командам оболочки: grepопция -E( --extended-regexp) позволяет избежать экранирования {}. Option -m 1( --max-count=1) останавливает ее после того, как найдена первая строка. Команда <in wcзаписывает файл в его стандартный ввод, чтобы предотвратить wcпечать имени файла вместе с длиной.
Какие самые длинные строки?
Чтобы сделать примеры более удобочитаемыми, когда имя файла встречается дважды, я буду использовать переменную fдля имени файла; Каждый $fв примере может быть заменен именем файла.
f="file.txt"
Показать первую самую длинную строку - первую строку длиной до самой длинной строки:
grep -E -m1 "^.{$(wc -L <"$f")}\$" "$f"
Показать все самые длинные строки - все строки длиной до самой длинной строки:
grep -E "^.{$(wc -L <"$f")}\$" "$f"
Показать последнюю самую длинную строку - последнюю строку длиной до самой длинной строки:
tac "$f" | grep -E -m1 "^.{$(wc -L <"$f")}\$"
Показать одну самую длинную строку - самая длинная строка длиннее всех других строк или ошибка:
[ $(grep -E "^.{$(wc -L <"$f")}\$" "$f" | wc -l) = 1 ] && grep -E "^.{$(wc -L <"$f")}\$" "$f"
(Последняя команда даже более неэффективна, чем другие, поскольку она повторяет полную команду grep. Очевидно, что она должна быть разложена таким образом, чтобы выходные данные wcи строки, записанные с помощью grep, сохранялись в переменные.
Обратите внимание, что все самые длинные строки могут фактически быть всеми строками Для сохранения в переменной необходимо сохранить только первые две строки.)