Найти / заменить внутри строки, только если строка не содержит определенной строки (awk) - PullRequest
1 голос
/ 24 мая 2019

Я пытаюсь воспроизвести команду awk, используя другой синтаксис. У меня есть файл (test.txt), который выглядит так:

>NAME_123_CONSENSUS
GACTATACA
ATACTAGA
>NAME2_48_TEST
ATAGCGA

и я надеюсь заменить все вхождения "A" на "1", используя другой синтаксис awk. Я могу решить это, используя следующую строку:

awk '!/_/{gsub("A", "1"); 1' test.txt

Однако я не могу получить тот же результат, используя цикл for,

awk '{for(j=1; j<=NF; j++) if ($j ~ "_") print; else print gsub("A","1")}' test.txt

, не используя следующий ввод

awk '{ if ($0 ~ "_") print $0; else print gsub("A", "1"); }' test.txt

Обе эти последние команды дают следующий вывод. Почему они дают разные выходные данные и чего мне не хватает, чтобы обе последние две команды дали желаемый результат?

>NAME_123_CONSENSUS
4
4
5
>NAME2_48_TEST
3

1 Ответ

1 голос
/ 24 мая 2019

Вы неправильно используете функцию gsub() здесь. Функция sub() / gsub() возвращает количество выполненных замен, а не измененную строку. Вы устанавливаете строку для изменения в качестве последнего аргумента и печатаете ее обратно

awk '{ for(j=1; j<=NF; j++) if ($j ~ "_") print; else { gsub("A","1",$0); print } }'

Тем не менее ваша первая команда является наиболее эффективным / кратким способом написания этого. Обратите внимание, что вы пропустили } в ОП. Должен быть записан как

awk '!/_/{ gsub("A", "1") }1'

Или используйте gensub(), доступный в GNU Awk's, который возвращает измененную строку, которую вы можете использовать для print. Подробнее об этом см. Строковые функции GNU Awk

awk '{ for(j=1; j<=NF; j++) if ($j ~ "_") print; else print gensub(/A/, "1", "g") }'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...