Печать части строк в текстовом файле между предопределенными тегами

Использование опции -oпараметра psпозволяет пользователю -задать формат вывода. Мы также можем отсортировать этот вывод для представления «top -25». Однако наложение параметра «лес» или иерархии процессов невозможно при выборе ps... --sort.... Добавление PPID к выходным данным может выявить иерархические отношения.

Конкретно в вашем случае мы могли бы сделать:

ps -e -ouser,time,cpu,vsz,ppid,pid,cmd --sort -time,user | head -26

Это упорядочивает выходные данные в порядке убывания времени (наибольшего значения, сначала ), а затем по пользователю внутри, чтобы дать 25 «верхних» процессов под строкой заголовка.

2
05.06.2021, 19:01
9 ответов

С awkможет быть:

$ awk -v FS="</?g>" '{print $2}' trsTest.txt
 Good wheatear
 The farm land is to be sold
 knock knock

Или если вы хотите сохранить теги:

$ awk -v FS="</g> " '{print $1 FS}' trsTest.txt
<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>
8
28.07.2021, 11:26

Вы можете просто использовать GNU grep и печатать только совпадающую часть(-o)строк:

grep -o '<g>.*<\/g>' trsTest.txt

Шаблон должен быть заключен в одинарные кавычки, чтобы оболочка не расширение символов (как*)

Эта первая команда выдаст:

<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>

Если вы не хотите включать теги, вы можете сделать это:

sed 's/.*<g>\(.*\)<\/g>.*/\1/' trsTest.txt

Это работает следующим образом:

  • сопоставить все, включая открывающий тег <g>
  • Я помню что-то между вышеперечисленным, используя \(и\)
  • соответствует всему, что находится после закрывающего тега <\g>до конца строки
  • Затем замените запомненным содержимым\1

Эта вторая команда выдаст:

 Good wheatear
 The farm land is to be sold
 knock knock
7
28.07.2021, 11:26

Сawk:

awk '{if (match($0, /<g>.*<\/g>/)) 
print substr($0,RSTART,RLENGTH); }' input

В этой команде встроенный -в функцию match()ищет регулярное выражение.

Из руководства по awk:

The match() function sets the predefined variable RSTART to the index. It also sets the predefined variable RLENGTH to the length in characters of the matched substring.

После нахождения индекса и длины регулярного выражения в текущей входной записи($0)встроенная -функция substr(target,start,length)получает ожидаемый результат.

Вы пробовали с awk '/<g>/, /<\/g>/' file. Эта команда использует шаблон диапазона, в котором два шаблона разделены запятой. Поскольку шаблон диапазона выбирает записей , вы получаете целую строку.

2
28.07.2021, 11:26

если теги всегда одинаковые, чтобы включить теги, используйте sed

sed 's/\(.*>\).*/\1/' trsTest.txt

вывод:

<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>

Updated to Quasimodo's more efficient code block

1
28.07.2021, 11:26

Если это XML, вы можете использовать синтаксический анализатор XML, такой как xmlstarlet. (Если это HTML, вы все еще можете использовать xmlstarlet, но вы должны предупредить его, что структура может быть нарушена.)

Я добавил ограничивающий элемент <root/>, чтобы входной XML-код был допустимым:

<root>
  <g> Good wheatear </g> other parts of line
  <g> The farm land is to be sold </g> other parts of line
  <g> knock knock </g> other parts of line
</root>

И затем команда для выбора </g>элементов и значений

xmlstarlet sel --template --match '//g' --copy-of '.' --nl file.xml

Выход

<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>

Преимущество xmlstarletпо сравнению с универсальными инструментами анализа текста, такими как sedили grep, заключается в том, что он понимает структуру XML, поэтому, если входной файл немного изменится, оставаясь действительным XML, xmlstarletпо-прежнему сможет чтобы разобрать его.

5
28.07.2021, 11:26

Другой способ сsed:

sed -n '
    s/<\/*g>/\n/g
    s/^\n/<g>/
    s/\n.*/<\/g>/
    p
' data
  • Изменить любую последовательность <g>и </g>на новую строку:s/<\/*g>/\n/g
  • заменить первую новую строку на открытый <g>тег:s/^\n/<g>/
  • замените все, что идет после последней новой строки, закрывающим тегом </g>:s/\n.*/<\/g>/
  • напечатать строку:p

Если вы также хотите удалить тег, команда sedстанет:

sed -n '
    s/<\/*g>/\n/g
    s/^\n//
    s/\n.*//
    p
' data
0
28.07.2021, 11:26
 awk -F "</g>" '{print $1"</g>"}' filename

выход

<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>
-1
28.07.2021, 11:26

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

С помощью функции gensub()(GNU awk)вы можете печатать содержимое между тегами <g>и </g>, включая теги :

.
awk '{print gensub(/(<g>.*<\/g>)(.*)/,"\\1","g")}' file
<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>

или без тегов:

awk '{print gensub(/(<g>)(.*)(<\/g>)(.*)/,"\\2","g")}' file
 Good wheatear
 The farm land is to be sold
 knock knock
1
28.07.2021, 11:26

Используя GNU sed, мы разрезаем строку до тех пор, пока подстрока <g>не появится впереди.

sed -n '
 ​/^<g>/!s|<g>|\n&|;/\n/D
 ​/^<g>/s|</g>|&\n|;/\n/P
' file

Метод с использованием Perl:

perl -ne ' print m{(<g>.*?</g>).*(.)}s' file
python3 -c 'import sys
ifile,s1,s2 = sys.argv[1:]
with open(ifile) as fh:
 for l in fh:
   p1 = l.find(s1)
   p2 = l.find(s2,p1)
   if p1 > -1 and p2 > -1:
     print(l[p1:p2+len(s2)])
' file '<g>'  '</g>'
1
28.07.2021, 11:26

Теги

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