У меня есть присвоение, выполняющее серию (n) awk команды в одном файле сценария. Ключ этого файла сценария должен отфильтровать определенные строки и записи этого файла оригинального текста здесь, названный студентами:
Frank Smith Engineering Senior C
John Doe Marketing Junior B
Nancy Jones Engineering Junior A
Betty Anderson Nursing Sophomore B
Bob Johnson History Freshman B
James Smith Economics Senior A
У меня есть эти команды awk в моем файле сценария testscript.script.
{print $2, $1, $3, $4, $5}
/A$/ {print $1, $2}
/!A$/ {print $1, $2}
На данный момент, когда я работаю nawk -f testscript.script students
Для первых нескольких строк вывода я добираюсь:
Smith Frank Engineering Senior C
Doe John Marketing Junior B
Jones Nancy Engineering Junior A
Nancy Jones
Anderson Betty Nursing Sophomore B
Johnson Bob History Freshman B
Smith James Economics Senior A
James Smith
Где, как Вы видите, вторая команда придала с первым, вместо того, чтобы быть разделенной, как желаемый.
Который приводит к моему вопросу: Как я могу разделить команды в сценарии оболочки, таком, что каждая новая команда имеет отдельный, независимый вывод от других?
Вы могли бы быть более обеспеченной записью сценария оболочки (скажите foo.sh
) с тремя командами awk вместо единственного awk сценария с тремя блоками:
#!/bin/sh
awk '{print $2, $1, $3, $4, $5}' "$1"
awk '/A$/ {print $1, $2}' "$1"
awk '/!A$/ {print $1, $2}' "$1"
Затем следующее должно дать желаемый результат:
sh foo.sh students
(Можно также сделать chmod +x foo.sh
и затем работать ./foo.sh students
.)
Это работает отлично, и как и следовало ожидать.
Ваша команда может быть переписана просто как:
awk '{print $2, $1, $3, $4, $5}; /A$/ {print $1, $2}; /!A$/ {print $1, $2}' students
это состоит из 3 awk
выражения:
{print $2, $1, $3, $4, $5}
/A$/ {print $1, $2}
/!A$/ {print $1, $2}
Все 3 выражения будут применены ко всем записям.
Первый перестраивает поля соответственно
Второй соответствует, если запись заканчивается в A
(/A$/
), раз так первые и вторые поля печатаются
Третий соответствует, если запись заканчивается в !A
, раз так первые и вторые печатаются
Поскольку первые две записи не удовлетворяют условие выражения 2, поля печатаются согласно выражению 1. То же идет для рекордного числа 4, и 5
Только запишите 3 и 6 условий соответствия 2-го выражения т.е. концов в A
так действие этого условия т.е. распечатать первые два поля в том, чтобы быть сделанным правильно после выполняющегося выражения 1 т.е. распечатать перестроенные поля. Таким образом, два действия применяются для рекордных 3 и 6. Я думаю, что это - то, что сбило Вас с толку.
Ни одна из записей не соответствует условию выражения 3 т.е. концов в !A
, возможно, Вы означали использовать условие как !/A$/
т.е. записи, который не заканчивается в A
(и примените желаемое действие).
Первые две проблемы, которые бросились мне в глаза:
!/A$/
, а не /!A$/
, так как я полагаю, вы не хотите сопоставить строки, заканчивающиеся литералом !A
, но строки, не заканчивающиеся на A
/B$/
, чтобы понять, что я имею в виду. К счастью, строки, оканчивающиеся на A
, не имеют пробелов в конце, поэтому ваше выражение /A$/
все еще работает, но его следует считать хрупким, поэтому $5=="A"
следует отдавать предпочтение в любом случае. На ваш главный вопрос, как «отделить» вывод каждой строки, я думаю, что проще всего использовать перенаправления файлов. т.е.
{print $2, $1, $3, $4, $5 >"students-reorderd-columns"}
$5=="A"{print $1, $2 >"a-students"}
$5!="A"{print $1, $2 >"non-a-students"}
Но если вам действительно нужно вывести это на стандартный вывод и вы хотите избежать cat student-reordered-columns a-students non-a-students
и временных файлов, вы можете заглянуть в sprint вместо этого
и собирает вывод в переменных и печатает их в блоке END
(что должно быть хорошим упражнением для читателя).