где и как работает сервер NFS и его клиент?

Иногда при выполнении через сетевое соединение (в частности, при изменении разрешений, например, с использованием sudo ) информация о размере терминала не распространяется на удаленную машину. Когда это происходит, конечно, некоторые программы не понимают, когда форматировать вывод, переносить строки и т. Д.

Обычно вы можете использовать программу resize , чтобы запросить у терминала его ширину, и исправить это . Вы бы запустили это на удаленном компьютере, и он отправил бы escape-символы, чтобы запросить у терминала его размер, а затем он обновил бы представление удаленной машины о фактическом размере.

7
20.03.2019, 21:52
6 ответов

Я не думаю, что это выполнимо с grep, но это возможно с AWK:

#! /usr/bin/awk -f

/FOO/ {
  matched = 1
  if (notfirst) print ""
  notfirst = 1
}

/^$/ {
  matched = 0
}

matched

С подсчетом совпадений:

#! /usr/bin/awk -f

/FOO/ {
  matched = 1
  if (matches) print ""
  printf "Match %d\n", ++matches
}

/^$/ {
  matched = 0
}

matched

В обоих случаях первые два блока определяют, следует ли копировать текущую запись на выход. Когда текущая запись соответствует «FOO», первый блок устанавливает matchedв 1,при необходимости выводит пустую запись (для отделения предстоящего вывода от предыдущего совпадения ); во втором варианте также увеличивает счетчик matchesи выводит заголовок. Когда текущая запись пуста, второй блок устанавливает matchedв 0. Условие одиночества matchedпечатает текущую запись, если matchedравно 1.

5
27.01.2020, 20:13

Я включил решение pcregrepи решение python.

Многострочное решение Grep

Если у вас установлено pcregrep, вы можете использовать многострочный шаблон, такой как ^.*FOO.*$\n?(^.*\S.*$\n?)*, например.:

pcregrep -M '^.*FOO.*$\n?(^.*\S.*$\n?)*' test.txt

Подвыражение ^.*FOO.*$\n?будет соответствовать любой строке, содержащей строку FOO, а подвыражение (^.*\S.*$\n?)*будет соответствовать любому количеству последующих строк, содержащих не -пробельный символ.

Решение Python

Вот скрипт Python, который должен делать то, что вы хотите:

#!/usr/bin/env python3
# -*- encoding: utf8 -*-
"""grep_follow.py

Search a text file for a pattern,
and output that pattern and the
non-empty lines which immediately follow it.
"""

import re
import sys

# Get the search pattern and the input file as command-line arguments
pattern = sys.argv[1]
input_file = sys.argv[2]

# Set a flag to determine whether or not to output the current line
print_flag = False

with open(input_file, "r") as _input_file:

    # Iterate over the lines of the input file
    for line in _input_file:

        # Remove trailing whitespace
        line = line.rstrip()

        # If the line is empty, stop producing output
        if not line.strip():
            print_flag = False

        # If the line matches the search pattern, start producing output
        elif re.search(pattern, line):
            print_flag = True

        # If the print flag is set then output the line
        if print_flag:
            print(line)

Вы бы запустили это так:

$ python grep_follow.py FOO test.txt
this line contains FOO
this line is not blank
This line also contains FOO
This line contains FOO too
Not blank
Also not blank
FOO!
Yet more random text
FOO!
2
27.01.2020, 20:13

Использование awkвместоgrep:

awk '/FOO/ { if (matching) printf("\n"); matching = 1 }
     /^$/  { if (matching) printf("\n"); matching = 0 }
     matching' file

Версия, которая перечисляет совпадения:

awk 'function flush_print_maybe() {
         if (matching) printf("Match %d\n%s\n\n", ++n, buf)
         buf = ""
     }
     /FOO/ { flush_print_maybe(); matching = 1 }
     /^$/  { flush_print_maybe(); matching = 0 }
     matching { buf = (buf == "" ? $0 : buf ORS $0) }
     END   { flush_print_maybe() }' file

Обе awkпрограммы используют очень простой «конечный автомат», чтобы определить, соответствует ли он в данный момент или нет. Совпадение шаблона FOOприведет к переходу в состояние matching, а совпадение шаблона^$(с пустой строкой )приведет к переходу в состояние, отличное от -matching.

Вывод пустых строк между совпадающими наборами данных происходит при переходах состояний изmatching(либо в matching, либо в не-matching).

Первая программа печатает любую строку в состоянии matching.

Вторая программа собирает строки в переменной buf, когда находится в состоянии matching. Он сбрасывает (очищает )это после возможной печати (в зависимости от состояния )вместе с меткой Match Nпри переходах между состояниями (, когда первая программа выводит пустую строку ).

Вывод этой последней программы на примере данных:

Match 1
this line contains FOO
this line is not blank

Match 2
This line also contains FOO

Match 3
This line contains FOO too
Not blank
Also not blank

Match 4
FOO!
Yet more random text

Match 5
FOO!
9
27.01.2020, 20:13
sed -ne '/FOO/{x;P;x};/FOO/,/^$/p' testfile

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

Это

  1. подавляет вывод(-n);тогда
  2. печатает пустую строку перед каждым вхождением "FOO"(/FOO/{x;P;x}-использует пустое место хранения );
  3. выбирает диапазоны строк, начиная с тех, которые содержат FOO(/FOO/)и заканчивая пустыми строками(/^$/); и, наконец,
  4. печатает эти строки(p).

this line contains FOO
this line is not blank


This line also contains FOO


This line contains FOO too
Not blank
Also not blank


FOO!
Yet more random text

FOO!
6
27.01.2020, 20:13
awk '/FOO/{print "===match " ++i "==="} /FOO/,/^$/' file

===match 1===
this line contains FOO
this line is not blank

===match 2===
This line also contains FOO

===match 3===
This line contains FOO too
Not blank
Also not blank

===match 4===
FOO!
Yet more random text
===match 5===
FOO!

Аналогичный вариант, в котором FOOможно было легко заменить на что-то другое:

awk -vpat=FOO '$0~pat{print "===match " ++i "==="} $0~pat,/^$/' file

Опускание завершающей пустой строки в печати по умолчанию оставляется читателю в качестве упражнения;-)

1
27.01.2020, 20:13

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

gawk '/FOO/{p=1} {if(p) print} /^$/{p=0}' infile.txt

Первое правило устанавливает p=1, если видит FOO. Второе правило печатает текущую строку, если p не равно нулю. Третье правило устанавливает p=0, если уже напечатанная строка ()пуста. Поменяйте местами второе и третье правила, если вы не хотите, чтобы выводился пустой разделитель строки.

Это вариант, который нумерует и разделяет совпадения, если есть несколько экземпляров FOO, не разделенных пустыми строками

gawk '/FOO/{p=1; n++; print "\n" n} /^$/{p=0} //{if (p) print $0 }' infile.txt
0
27.01.2020, 20:13

Теги

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