#awk
Вопрос:
У меня есть такой текстовый файл:
VAREAKAVVLRDRKSTRLN 2888
ACP*VRWPIYTACGP 292
RDRKSTRLNSSHVVTSRMP 114
VAREA*KAVVLRDRRAHV*T 73
в 1 — м столбце в некоторых строках есть « *
«. Я хочу удалить все строки с этим « *
. вот ожидаемый результат:
ожидаемый результат:
VAREAKAVVLRDRKSTRLN 2888
RDRKSTRLNSSHVVTSRMP 114
для этого я использую этот код:
awk -F "t" '{ if(($1 == '*')) { print $1 "," $2} }' infile.txt > outfile.txt
этот код не возвращает ожидаемый результат. как я могу это исправить?
Комментарии:
1. Что касается
$1 == '*'
— вы не можете использовать'
в'
скрипте с разделителями. Видишь unix.stackexchange.com/a/670702/133219 .
Ответ №1:
как я могу это исправить?
Ты сделал
awk -F "t" '{ if(($1 == '*')) { print $1 "," $2} }' infile.txt > outfile.txt
делая $1 == "*"
это, вы спрашиваете: является ли первое поле *
не содержит *
первого ? Вы можете использовать функцию индекса, которая возвращает позицию совпадения, если она найдена, или 0 в противном случае. Пусть infile.txt
содержание будет
VAREAKAVVLRDRKSTRLN 2888
ACP*VRWPIYTACGP 292
RDRKSTRLNSSHVVTSRMP 114
VAREA*KAVVLRDRRAHV*T 73
затем
awk 'index($1,"*")==0{print $1,$2}' infile.txt
выход
VAREAKAVVLRDRKSTRLN 2888
RDRKSTRLNSSHVVTSRMP 114
Обратите внимание, что если вы используете index
вместо шаблона /
… /
вам не нужно заботиться о символах с особым значением, например .
. Обратите внимание, что для имеющихся у вас данных вам не нужно явно устанавливать разделитель полей ( FS
). Важно '
не является законным разделителем строк в GNU AWK
, вы должны использовать "
его для этой цели, если только ваше намерение не состоит в том, чтобы вызвать труднодоступные ошибки.
(проверено в gawk 4.2.1)
Комментарии:
1.
'index($1,"*")==0{print $1,$2}'
='!index($1,"*")'
.2. Ничто в вашем сценарии не является «только для глаз», кстати, он будет вести себя так же в любом случае.
3. @EdMorton Я исправил свой ответ, я не знал, что в GNU
AWK
есть трюк для сравнения поля со списком файлов в каталоге, из которого я выполняю эту команду.4. на самом деле я ошибался в этом комментарии, но то, что я имел в виду, не имело ничего общего с awk.
*
Внутри'
s отображается оболочка, поэтому я думал, что оболочка расширит ее до файлов в текущем каталоге, но я просто попробовал, и этого не произошло (и мне лень думать о том, почему!).5. Ах, я знаю почему — потому что оболочка включает остальную часть сценария awk в шаблон глобулирования, точно так же, как если бы вы писали
ls 'foo'*'bar'
, а неls 'foo' * 'bar'
.
Ответ №2:
с показанными вами образцами, пожалуйста, попробуйте следующую awk
программу.
awk '$1!~/*/' Input_file
ИЛИ выше будет напечатана полная строка, если условие НЕ соответствует, в случае, если вы хотите напечатать только 1-е и 2-е поля строки соответствующего условия, попробуйте выполнить следующие действия:
awk '$1!~/*/{print $1,$2}' Input_file
Ответ №3:
Используйте grep
это, чтобы удалить строки, содержащие буквальную звездочку ( *
). Обратите внимание, что он должен быть экранирован обратной косой чертой ( *
) или помещен в класс символов ( [*]
), чтобы grep
его нельзя было интерпретировать *
как модификатор, означающий 0 или более символов:
echo "A*BnCD" | grep -v '[*]'
CD
Здесь GNU grep
использует следующие параметры:
-v
: Выводите строки, которые не совпадают.