Вы можете превратить параграфы в отдельные строки, использовать grep -f matchfile
для результата, а затем восстановить новые строки:
sed '/^$/s/^/\x02/' myfile | tr \\n$'\002' $'\003'\\n \
| grep -f matchfile | tr $'\003' \\n | head -n -1
Вы можете обойтись без head
, если пустая строка в конце вывода вас не беспокоит.
Итак... sed
добавляет \x02
в начало каждой пустой строки, затем tr
переводит все новые строки в \x03
и все \x02
в новые строки (эффективно превращая все абзацы в отдельные строки, где исходные строки являются полями, разделенными некоторым низким символом ascii, который вряд ли встретится в вашем текстовом файле). в данном случае \x03
), затем grep
выбирает только совпадающие "строки"; наконец, второй tr
восстанавливает новые строки и head
отбрасывает пустую строку в конце (вы можете использовать любой другой инструмент, например, sed
). например,
sed \$d
).
На самом деле, самый простой способ понять, как это работает, - запустить это пошагово: выполните только 1-ю команду, затем 1-ю и 2-ю и так далее... и наблюдайте за выводом - он должен быть самоочевидным1.
1: если вы ознакомились с tr
после прочтения руководства...
Некоторые идеи с GNU awk:
$ awk '{match($0,/(...)(...)(.*)/,a);printf("(%s)%s-%s\n",a[1],a[2],a[3])}' <<<"333456789"
(333)456-789
$ awk '{match($0,/(...)(...)(.*)/,arr);printf( "(" arr[1] ")" arr[2] "-" arr[3])}' <<<"333456789"
(333)456-789
$ awk '{a=$0;printf("(%s)%s-%s\n",substr(a,1,3),substr(a,4,3), substr(a,7))}' <<<"333456789"
(333)456-789
Чтобы адаптировать его к вашему скрипту, попробуйте этот:
Замена последней строки скрипта:
printf( fmtstr, week[d], cname, name2phone[ cname])
Ниже, должно работать нормально:
ph=name2phone[ cname];
match(ph,/(...)(...)(.*)/,arr);
printf( fmtstr, week[d], cname, "(" arr[1] ")" arr[2] "-" arr[3])
perl -F, -lane '
@ARGV and $Phone_of{$F[0]} = $F[1] =~ s/(...)(...)(.*)/($1)$2-$3/r;
@ARGV or $Person_of{uc $F[1]} = $F[0];
END {
$fmt = join "\t", map { qq/%${_}s/ } qw/ -10 1 1 /;
print sprintf $fmt, qw/ Day Name Phone /;
print "_" x 37;
for my $day ( map { uc($_ . day) } qw/ sun mon tues wednes thurs fri satur / ) {
print sprintf $fmt, $day, $Person_of{$day} || "Nobody", $Phone_of{$Person_of{$day}};
}
}
' project2.phone project2.day
Сначала мы заполняем хэш % Phone_of
ключами в качестве имен и значениями их телефонных номеров. Затем, когда @ARGV
обнуляется, т. Е. Обрабатывается последний файл (.day), мы заполняем хэш % Person_of
ключами в виде дня в верхнем регистре и значением в виде человека, работающего в этот день.
В блоке END {...}
, когда оба файла были обработаны, мы сначала устанавливаем строку формата и с ее помощью печатаем заголовок. Наконец, мы перебираем дни недели (в верхнем регистре) и отображаем день, человека, работающего в этот день (или никого, если в этот день никто не работает), и номер телефона человека.
Day Name Phone
_____________________________________
SUNDAY Tom (248)496-2204
MONDAY Nobody
TUESDAY Barry (313)123-4567
WEDNESDAY Alden (616)556-4458
THURSDAY Dave (734)838-9800
FRIDAY Carl (248)344-5576
SATURDAY Marci (313)449-1390
No whitespace(s) in the input files (*.phone, *.day)
{
raw=$3; //or whichever column the phone# is in
area=substr(raw,1,3);
prefix=substr(raw,4,3);
suffix=substr(raw,7);
print $1, $2, "("area")"prefix"-"suffix
}
у меня работает