удаление строк со специальными символами в awk

#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 : Выводите строки, которые не совпадают.