Вопрос или проблема
Дан файл input.txt
с содержимым:
xyMnZnMs76XHgsWJ
size: YN3hxFqFeUxXUMrQ
USPqYEnbquwFhUW7
vhJJduHZu25qHzTw
size: JaTDhQYQtLRWBLjj
uE5HGDAZN6DHU73Q
QxVPfQQaKTgR9LXQ
grnsm8bwSz5fJbQS size:
7CcuZxCHSJYhcdqg
ZuWadAaLWFwDwj5Z
как использовать if (condition) {...} else {...}
?
Я пытался использовать:
awk -F ':' '
IF ($1 ~ /size/) {
print "match: "$0;
} ELSE {
print "non-match: "$0;
}' input.txt
но все строки соответствуют (даже те, где $1
не содержит "size"
):
match: xyMnZnMs76XHgsWJ
match: size: YN3hxFqFeUxXUMrQ
match: USPqYEnbquwFhUW7
match: vhJJduHZu25qHzTw
match: size: JaTDhQYQtLRWBLjj
match: uE5HGDAZN6DHU73Q
match: QxVPfQQaKTgR9LXQ
match: grnsm8bwSz5fJbQS size:
match: 7CcuZxCHSJYhcdqg
match: ZuWadAaLWFwDwj5Z
Я ожидаю, что вывод будет:
non-match: xyMnZnMs76XHgsWJ
match: size: YN3hxFqFeUxXUMrQ
non-match: USPqYEnbquwFhUW7
non-match: vhJJduHZu25qHzTw
match: size: JaTDhQYQtLRWBLjj
non-match: uE5HGDAZN6DHU73Q
non-match: QxVPfQQaKTgR9LXQ
non-match: grnsm8bwSz5fJbQS size:
non-match: 7CcuZxCHSJYhcdqg
non-match: ZuWadAaLWFwDwj5Z
Давайте объясним.
Синтаксическая структура для awk
— это » pattern {
action }
«, где любой из компонентов (но не оба вместе) является необязательным. Когда вы написали IF ($1 ~ /size/) { print "match: "$0; }
, вы не использовали ключевое слово if
, а фактически конкатенировали пустую строку (неустановленную переменную IF
) и выражение ($1 ~ /size/
), которое оценивается либо в 0
, либо в 1
. Из-за конкатенации строк результат рассматривается как строка (“0
” или “1
“) и считается “истинным”, если она имеет ненулевую длину. Любой результат имеет длину, поэтому условие шаблона считается безусловно истинным. На этом этапе {
action }
запускается, и выполняется print "match: "$0
.
Давайте исправим.
Изучив документацию для awk
(см. man awk
), вы обнаружите, что структура if
…else
пишется в нижнем регистре. Более того, вы не можете использовать такую структуру за пределами » {
action }
« части каждого оператора.
awk -F: '
{ if ($1 ~ /size/) { print "match:", $0 } else { print "non-match:", $0 } }
' input.txt
Однако обратите внимание, что ваша строка grnsm8bwSz5fJbQS size:
рассматривается как несоответствие в вашем требуемом выходе, но в этом коде выводится как соответствие. Это связано с тем, что регулярное выражение /size/
соответствует первому полю, разделенному двоеточиями, grnsm8bwSz5fJbQS size
. Вам нужно было бы определить начало и конец строки для точного совпадения — но лучше сравнить как буквальную строку:
awk -F: '
{ if ($1 == "size") { print "match:", $0 } else { print "non-match:", $0 } }
' input.txt
Или,
awk -F: '
$1 != "size" { print "non-match:", $0 }
$1 == "size" { print "match:", $0 }
' input.txt
И даже,
awk -F: '
$1 != "size" { printf "non-" }
{ print "match:", $0 }
' input.txt
Для этого я даже не использовал бы if-statement
, они предназначены для более сложных вещей. Вы могли бы сделать просто так:
awk -F':' '/^size/ {print "match: " $0} !/^size/ {print "non-match: " $0}' input.txt
или мой предпочтительный способ заключается в использовании переменной, называемой pat
, чтобы вы могли изменить её позже более легко:
awk -v pat="size" -F':' '$1~pat {print "match: " $0}; $1!~pat {print "non-match: " $0}' input.txt
Это работает для меня:
awk -F: '{if ($1 =="size") {print "match: "$0} else {print "non-match: "$0}}'
С awk
вы всегда должны использовать фигурные скобки для кода, например:
awk '{ ваш код }'
Также if
/else
пишется не заглавными буквами.
Вы можете найти дополнительные примеры здесь.
.
Ответ или решение
Когда мы говорим об использовании условия if
в awk
, важно понимать структуру и синтаксис этого мощного инструмента для обработки текстовых данных в Unix-подобных системах. Рассмотрим данный случай на примере файла input.txt
со следующим содержимым:
xyMnZnMs76XHgsWJ
size: YN3hxFqFeUxXUMrQ
USPqYEnbquwFhUW7
vhJJduHZu25qHzTw
size: JaTDhQYQtLRWBLjj
uE5HGDAZN6DHU73Q
QxVPfQQaKTgR9LXQ
grnsm8bwSz5fJbQS size:
7CcuZxCHSJYhcdqg
ZuWadAaLWFwDwj5Z
Проблема заключалась в том, что неправильно использовалась конструкция if
в awk
, из-за чего все строки файла неправильно классифицировались как совпадающие. Рассмотрим, как можно использовать условие if
корректно:
-
Исправление ошибки: Изначально использовалась конструкция
IF
, которая неверна, так как вawk
отсутствует поддержка заглавных букв для ключевых слов.awk
чувствителен к регистру и следует использовать ключевые слова с маленькой буквы. -
Синтаксис
awk
: Для написания условийif
иelse
вawk
, необходимо помещать их внутрь блока действий{}
. Вот исправленный пример:awk -F: ' { if ($1 ~ /size/) { print "match:", $0 } else { print "non-match:", $0 } } ' input.txt
-
Корректное использование регулярных выражений: Следует учитывать, что выражение
$1 ~ /size/
будет находить совпадения в первых полях, содержащих текстsize
. Если нужно точно искать строки, начинающиеся сsize
, лучше использовать оператор сравнения==
:awk -F: ' { if ($1 == "size") { print "match:", $0 } else { print "non-match:", $0 } } ' input.txt
-
Упрощение без
if
-conditions: В данном случае, использование условия можно упростить, воспользовавшись следующей конструкцией:awk -F':' '/^size/ {print "match:", $0} !/^size/ {print "non-match:", $0}' input.txt
-
Использование переменных для гибкости: Чтобы ваша программа была более адаптируема, можно ввести переменную
pat
, что упростит возможные изменения:awk -v pat="size" -F':' '$1 ~ pat { print "match:", $0 } $1 !~ pat { print "non-match:", $0 }' input.txt
Этот подход более точно удовлетворит ваши цели и улучшит читаемость кода. Если у вас возникнут дополнительные вопросы касательно обработки файлов с использованием awk
, рассмотрите углубленное изучение документации и практических примеров.