Строки извлечения из файла, содержащего От <str1> До <str2>

ls имеет a -L опция, которая будет эффективно преследовать символьные ссылки и показывать перманент, владельца, inode, и т.д. окончательного объекта. [Это делает это путем выполнения stat(target) вместо lstat(target)]. Для лучших результатов, выполненных как корень или как кто-то, у кого есть доступ для чтения к соответствующим смонтированным файловым системам.

Таким образом в Вашем случае, попробуйте следующее:

find / -exec ls -iLd {} | grep inodenum

[скопированный с моего комментария, на запрос OP.]

2
18.09.2018, 13:09
5 ответов

Использование sed

Этот ответ предполагает, что у вас есть sed хорошего качества, который может обрабатывать длинные строки. Предполагая, что ваш текст находится в файле с именем file :

$ tr '\n' '\001' <file | sed -n -r 's/.*(how.*catch).*/\1\n/p' | tr '\001' '\n' 
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch

Объяснение:

  • tr '\ n' '\ 001'

    Читается из файла file и заменяет все символы новой строки восьмеричными символами 001. Это приводит к преобразованию ввода в одну строку.

  • sed -n -r 's /.* (how. * Catch). * / \ 1 \ n / p'

    Теперь, когда ввод - одна строка, sed может обрабатывать эта задача легко. Приведенная выше команда подстановки захватывает весь текст от «как» до «поймать» и выводит его на стандартный вывод

    . Поскольку используется параметр -n , ничего не печатается, если не соответствует регулярное выражение. Таким образом, если на входе нет последовательности how. * Catch , ничего не печатается.

  • tr '\ 001' '\ n'

    Преобразует восьмеричные символы 001 обратно в символы новой строки.

Восьмеричное 001 может быть заменено любым символом, который (а) вы уверены, что его нет во входном файле и (б) ваш sed может правильно обрабатывать.

Использование awk

$ awk '/how/{f=1;sub(/.*how/,"how")} /catch/{f=0;sub(/catch.*/,"catch");print} f' file
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch

Объяснение:

  • / how / {f = 1; sub (/.* how /, «как»)}

    Если строка содержит слово «как», это удаляет весь текст, предшествующий "как", и устанавливает для переменной флага f значение 1

  • / catch / {f = 0; sub (/ catch. * /, "catch"); print}

    Если строка содержит слово «catch», это удаляет весь текст после «catch», устанавливает флаговую переменную f в 0 и печатает исправленную строку.

  • f

    Если флаг равен 1, эта несколько загадочная команда awk вызовет печать строки. Если f == 0 , то ничего не печатается.

2
27.01.2020, 21:50

Вы можете сделать это через Perl,

$ perl -000pe 's/.*(how.*?catch).*/\1\n/s' file
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch
1
27.01.2020, 21:50

Пример sed будет неудачным, если текст не является частью файла, то вы получите полный файл вместо ничего.

Использовать grep вместо sed:

tr '\n' '\001' < file | grep -o -E 'how.*catch' | tr '\001' '\n' 

жадное и не жадное совпадение тоже проблематично, поэтому если "catch" находится во второй строке, а другой - в пятой, то вы хотите не жадное совпадение.

Читайте здесь, как этого добиться, во многом зависит от версии grep:

https://stackoverflow.com/questions/3027518/non-greedy-grep

1
27.01.2020, 21:50

Если у вас есть версия grep , поддерживающая PCRE, вы можете использовать следующую команду, чтобы делать то, что вы хотите:

$ grep -Pzo 'how.*\n.*catch' file 
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch

Переключатели:

  • -P - включает PCRE - Perl-совместимые регулярные выражения
  • -z - Вывести нулевой байт (символ ASCII NUL) вместо символа, который обычно следует за именем файла. Например, grep -lZ выводит нулевой байт после каждого имени файла вместо обычного символа новой строки. Эта опция делает вывод однозначным даже при наличии имен файлов, содержащих необычные символы, такие как символы новой строки. Эту опцию можно использовать с такими командами, как find -print0, perl -0 , sort -z и xargs -0 для обработки произвольных имен файлов, даже тех, которые которые содержат символы новой строки.
  • -o - печатать только совпавшие (непустые) части совпадающей строки, с каждой такой частью в отдельной строке вывода.
4
27.01.2020, 21:50

Подходящим инструментом для этой работы является pcregrep

pcregrep -oM "how(.|\n)*catch" SPEC
  • pcregrep : grep с Perl-совместимыми регулярными выражениями.
  • -o : показать только ту часть строки, которая соответствует шаблону
  • -M : разрешить шаблонам соответствовать более чем одной строке
  • (. | \ N) * : сопоставить любой символ или новую строку ноль или более раз

Если вы хотите, чтобы версия была не жадной, добавьте ? после * :

pcregrep -oM "how(.|\n)*?catch" SPEC
3
27.01.2020, 21:50

Теги

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