Несколько строк несколько строк в одну строку

> echo blablablaWANTEDTEXT[TEXTTOCOPY]blablabla... | 
> awk -v searchtext=WANTEDTEXT '$0 ~ searchtext "\\[.*\\]" {
    strstart=index($0,searchtext "[")+length(searchtext)+1;
    tmpstr=substr($0,strstart); sub("].*$","",tmpstr); print tmpstr; } '

TEXTTOCOPY
2
29.09.2019, 17:27
3 ответа

Сperl

$ cat ip.txt
abc def ghi 123 345 456 
abc def def ghi 123 345 456
abc def def def ghi 123 345 456 1234

$ perl -lane 'print join " ", grep { /def|123/ } @F' ip.txt
def 123
def def 123
def def def 123 1234

$ perl -lane 'print join " ", grep { $_ eq "def" || $_ eq "123" } @F' ip.txt
def 123
def def 123
def def def 123
  • -laneздесь -lудалит новую строку из строки ввода и добавит ее обратно, когда используется print, -aавтоматически разделит строку ввода на пробелы и сохранит результаты в массиве @F, -nбудет перебирать строки ввода но не будет автоматически печатать строки после обработки и -eпозволяет предоставить сценарий Perl из командной строки
  • grep { /def|123/ } @Fбудет фильтровать все элементы массива @F, если они содержат defили 123
    • если вы хотите совпадение строки вместо регулярного выражения, вы можете использоватьgrep { $_ eq "def" || $_ eq "123" } @F
  • print join " "вывести элементы, полученные из вывода grepс пробелом в качестве разделителя
1
27.01.2020, 22:08

Вы можете использовать awkи оставить только нужные поля:

echo -e "abc def bac 123\nabc def def bac 123\nabc def def def bac 123 123" \
  | awk -v var1="def" -v var2="123" '{
  i=0
  for (j=1; j<=NF; j++){
    if ($j==var1 || $j==var2){ $++i=$j }
    if (i!=j){ $j="" }
  }
  print
}'

Это перебирает поля в цикле for -и переназначает defили 123следующему полю $++i=$j(, начиная с индекса 0, поэтому первое поле равно 1, следующее — 2... )и сбрасывает текущее поле $jв пустую строку ($j=""), если индекс iне является индексом цикла j.

Выход:

def 123
def def 123
def def def 123 123
0
27.01.2020, 22:08

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

$ cat test.txt
abc def ghi 123 345 456 
abc def def ghi 123 345 456
abc def def def ghi 123 345 456
$ printf '%s\n' 'g/^/.!awk -v ORS=" " -v RS=" " "/^(def|345)$/"' %p | ex test.txt
def 345 
def def 345 
def def def 345 
$ 

Это:

  1. Считывает файл в буфер (в ex), где его можно изменить, распечатать и/или сохранить;
  2. Фильтрует каждую отдельную строку буфера через awkскрипт (отдельно );
  3. Печатает все содержимое буфера (с помощью %p).

Приведенная выше команда не сохраняет результаты обратно в файл. Если вы хотите сделать это, просто замените %pна x.


Подробное объяснение:

ex— редактор файлов с поддержкой сценариев. Он принимает имя файла(test.txt)в качестве аргумента и принимает команды редактирования со своего стандартного ввода.

Здесь мы предоставляем команды редактирования, используя printf. Первый аргумент printf— это строка форматирования, в данном случае '%s\n', которая используется для управления выводом остальных аргументов printf. Мы говорим, что все аргументы будут строками, и после каждого должен быть напечатан символ новой строки. (Одинарные кавычки нужны для того, чтобы оболочка не интерпретировала обратную косую черту — мы хотим, чтобы printfполучал обратную косую черту, а не оболочка.)

Есть два аргумента, которые мы отправляем в exс помощью printf. Вот они:

g/^/.!awk -v ORS=" " -v RS=" " "/^(def|345)$/"
%p

Второй из них самый простой. %— диапазон адресов; это означает «весь буфер». p— это команда печати.Так что это просто означает «распечатать весь буфер».

Первый требует некоторого разбора.

g/.../— это «глобальная» команда. Он ищет во всем буфере строки, которые соответствуют заданному шаблону (, в данном случае ^, регулярному выражению, означающему «начало строки» ), и запускает следующую exкоманду редактирования для каждой такой строки. Поскольку каждая строка имеет начало строки, каждая строка соответствует ^, поэтому эффект заключается в выполнении следующей команды для каждой строки отдельно.

Тогда .— это адрес, означающий «текущая строка (буфера )». Поскольку он указан после команды g, он по очереди обращается к каждой строке буфера.

!используется для запуска команды оболочки. Когда он имеет префикс адреса (, в данном случае .), заданный диапазон строк (или одна строка )передается данной команде оболочки на стандартный ввод и результат (. ] стандартный вывод )команды помещается вместо этой строки буфера.

Другими словами, .!shell-command-hereв exозначает фильтровать текущую строку буфера с помощью некоторой внешней команды.

Итак, мы рассмотрели, как эта настройка команды фильтрует каждую строку буфера (по отдельности )с помощью команды awk; теперь давайте проанализируем эту команду awk:

awk -v ORS=" " -v RS=" " "/^(def|345)$/"

Вы можете определить переменные для awk, используя флаг -v. Таким образом, первые несколько аргументов задают для переменных ORSи RSодин пробел.

RSв awk— «разделитель записей»; по умолчанию его значением является новая строка. Какой бы символ он ни был установлен, awkиспользуется для разделения записей (обычно строк )по мере их считывания.

Точно так же ORS, «разделитель выходных записей», управляет тем, что awkиспользует для разделения записей (обычно строк )при их выводе на печать.

Установив каждый символ пробела,мы можем легко работать с каждым словом строки как с одной записью.

Следующая часть — это фактическая команда awk.(awk— это собственный язык сценариев.)awkблоки команд состоят из условий и действий; любой из них может быть опущен. Здесь условие /.../соответствует регулярному выражению, т. е. это условие применяется ко всем записям (слов, в данном случае ), которые соответствуют данному регулярному выражению. Частями регулярного выражения являются^(начало строки ),$(конец строки )и два возможных шаблона, сгруппированных в круглых скобках, разделенных вертикальной чертой|(), чтобы указать, что любой из этих шаблонов является приемлемо.

Поскольку после условия (нет действия, действие будет заключено в фигурные скобки для awk), действие awk по умолчанию "print" применяется к записям, соответствующим этому условию. (Помните, это означает, что awkнапечатает каждую совпадающую запись (слово )строки, а затем exпрочитает этот вывод и поместит его вместо строки (s )буфера, который exпередал в awkв первую очередь.)

Это решение делает упрощающее предположение, что все шаблоны будут сопоставляться с полными словами, т. е. вы не захотите сопоставлять какие-либо шаблоны, которые включают пробелы. Это соответствует примеру ввода, который вы дали в вопросе.

1
27.01.2020, 22:08

Теги

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