Awk не принимает переменную bash - PullRequest
0 голосов
/ 27 июня 2011

Я считаю, что эта команда отлично работает:

awk -v "/mallory:/,/end-config/ {next} 1" /filename.txt

В файле все выглядит так:

alice:
 config option 1
 config option 2
 end-config

mallory:          <--- Line gets deleted
 config option 1  <--- Line gets deleted
 config option 2  <--- Line gets deleted
 end-config       <--- Line gets deleted

bob:
 config option 1
 config option 2
 end-config

и удаляет только блок конфигурации для mallory.

Итак, теперь я хотел определить это в скрипте bash, чтобы имя пользователя могло быть переменной bash. Я сделал это:

#!/bin/bash
username="mallory"
awk -v username="$username" "/username:/,/end-config/ {next} 1" /file.txt

Угадай что. Это ничего не удаляет. Вывод соответствует файлу, с которого я начал. Что дает? Я правильно импортировал свою переменную, верно?

Ответы [ 5 ]

1 голос
/ 27 июня 2011

В качестве альтернативы, вы можете использовать

#!/bin/bash
username="mallory"
awk -v  "/${username}:/,/end-config/ {next} 1" /file.txt

Помните, что оболочка выполнит интерполяцию оболочки до того, как программа перейдет в AWK, поэтому ${username} будет заменено на mallory. Чтобы быть более безопасным, вы можете использовать

#!/bin/bash
username="mallory"
awk -v '/'"${username}"':/,/end-config/ {next} 1' /file.txt

, которая обеспечит защиту программы awk от любой другой интерпретации оболочки.

1 голос
/ 27 июня 2011

/foo/,/bar/ - это диапазон адресов, где будет работать ваш оператор {next}.И адреса должны быть литералами.Ответ Geekosaur работает с небольшим изменением:

awk -v username="mallory" '
    $0 ~ (username ":"),/end-config/ {next}
    1' filename.txt

1 необходим для awk, чтобы сделать что-нибудь.Лучшим способом может быть:

awk -v username="mallory" '
    $0 ~ (username ":"),/end-config/ {next}
    {print $0}' filename.txt

. В котором говорится, что вы печатаете строку {print $0}, если вы не пропустите ее с помощью оператора {next}.Awk печатает строку, если не дано никаких других команд, и возвращает true (ненулевое) значение.

0 голосов
/ 12 мая 2013

/username:/ точно соответствует строке, которую вы написали, и не имеет ничего общего с переменной окружения, но awk может читать переменные окружения.Я бы предложил:

username=mallory
awk '$0 == ENVIRON["username] ":",/end-config/ {next} 1' /file.txt

На самом деле это не самое лучшее решение, так как в результате появляются двойные пустые строки.Поэтому, если установлено значение username=mallory, то результат будет таким:

alice:
 config option 1
 config option 2
 end-config


bob:
 config option 1
 config option 2
 end-config

Но, может быть, это нормально для Вас.

0 голосов
/ 28 июня 2011

немного короче с помощью sed - сохраните следующее в файл, например. confdel.sh

sed "/^$1:/,/end-config/d"

и используйте его как:

bash confdel.sh mallory < config_file.txt
0 голосов
/ 27 июня 2011
"/username:/,/end-config/ {next}"

username будет буквально там.Для сопоставления с переменной необходимо использовать явное сопоставление с образцом:

awk -v username="mallory" '
    $0 ~ (username ":"),/end-config/ {next}
    1'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...