Разделение команд в файле сценария?

У меня есть присвоение, выполняющее серию (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

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

Который приводит к моему вопросу: Как я могу разделить команды в сценарии оболочки, таком, что каждая новая команда имеет отдельный, независимый вывод от других?

0
задан 17 October 2016 в 06:52

3 ответа

Вы могли бы быть более обеспеченной записью сценария оболочки (скажите 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.)

1
ответ дан 28 September 2019 в 09:33

Это работает отлично, и как и следовало ожидать.

Ваша команда может быть переписана просто как:

awk '{print $2, $1, $3, $4, $5}; /A$/ {print $1, $2}; /!A$/ {print $1, $2}' students

это состоит из 3 awk выражения:

  1. {print $2, $1, $3, $4, $5}

  2. /A$/ {print $1, $2}

  3. /!A$/ {print $1, $2}

Все 3 выражения будут применены ко всем записям.

  • Первый перестраивает поля соответственно

  • Второй соответствует, если запись заканчивается в A (/A$/), раз так первые и вторые поля печатаются

  • Третий соответствует, если запись заканчивается в !A, раз так первые и вторые печатаются

  • Поскольку первые две записи не удовлетворяют условие выражения 2, поля печатаются согласно выражению 1. То же идет для рекордного числа 4, и 5

  • Только запишите 3 и 6 условий соответствия 2-го выражения т.е. концов в A так действие этого условия т.е. распечатать первые два поля в том, чтобы быть сделанным правильно после выполняющегося выражения 1 т.е. распечатать перестроенные поля. Таким образом, два действия применяются для рекордных 3 и 6. Я думаю, что это - то, что сбило Вас с толку.

  • Ни одна из записей не соответствует условию выражения 3 т.е. концов в !A, возможно, Вы означали использовать условие как !/A$/ т.е. записи, который не заканчивается в A (и примените желаемое действие).

2
ответ дан 28 September 2019 в 09:33

Первые две проблемы, которые бросились мне в глаза:

  1. Возможно, вы хотели сказать !/A$/, а не /!A$/, так как я полагаю, вы не хотите сопоставить строки, заканчивающиеся литералом !A, но строки, не заканчивающиеся на A
  2. Я не знаю, связано ли это с тем, как вы разместили свой пример здесь, или это так в вашем начальный набор данных, но некоторые строки содержат пробелы в конце. Например. попробуйте посмотреть, какие строки соответствуют /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 (что должно быть хорошим упражнением для читателя).

0
ответ дан 10 May 2020 в 05:40

Другие вопросы по тегам:

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