С помощью awk
awk '{x=$0; gsub(/[^[:alpha:]]/, "", x)};length(x) == 2' file
Это устанавливает каждую строку в переменную x
с последующей заменой всех неальфа-символов в пределах x
пустой строкой. Если длина измененного таким образом x
равна 2
, соответствующая строка квалифицируется как
Альтернативно, с grep
grep '^[^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*$' file
Сawk
:
awk '
$0 == "foo" {if (sep) print ""; sep = ""; inside = 1; next}
$0 == "bar" {inside = 0; next}
inside {printf "%s", sep $0; sep = " "}
END {if (sep) print ""}'
Чтобы сопоставить строки с foo
в качестве первого слова, замените $0 == "foo"
на $1 == "foo"
; чтобы соответствовать строкам, начинающимся с foo
, замените на/^foo/
(сокращение от$0 ~ /^foo/
).
Перл спешит на помощь!
perl -ne '
if ($e = /^foo$/.. /^bar$/) {
if ($e =~ /E/) { print "\n" }
else {
chomp;
print " " if $e > 2;
print if $e > 1;
}
}' -- input.txt
-n
считывает ввод построчно ..
— это оператор диапазона, он возвращает относительный номер строки для каждой строки в блоке. К последней строке добавлено E0
. Вы могли бы сделать и так:
a )Это POSIX-sed
совместимый код, в котором мы сохраняем средние -строки диапазона (!/foo/ и !/bar/ )в области удержания.
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!{H;$!d;}
s/.*//;x;s/^\n//;y/\n/ /
' input-file.txt
b )и с Perl
, как показано
perl -lne '
next unless /foo/... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
Пояснение:
/foo/
, и заканчивающийся на /bar/
, причем обе строки расположены на разных строках. @A
. После сохранения вернитесь для чтения следующей записи, предоставленной не eof. /bar/
или eof
, мы печатаем то, что находится в @A
, а также очищаем его, готовясь к следующему циклу сбора.