Отредактируйте /etc/resolvconf/update. d/libc
следующую строку
[ "$N" = 3 ] && return 0
To
[ "$N" = 4 ] && return 0
Теперь вы можете вставить 4 сервера имен в /etc/network/interfaces
, вставьте строку в ваш интерфейс
dns-nameservers x.x.x.x y.y.y.y a.a.a.a b.b.b.b
Ответ Иниана отлично работает, когда file2
состоит всего из одной строки, и это хорошее начало для более общего ответа. Но я верю, что
awk 'FNR == NR { neg[$1]; next } { ok=1; for (i in neg) if ($2 ~ i) ok=0; if (ok) print }' file2 FS="," file1
будет делать то, что вы хотите в целом. Как и ваш ответ, он начинается с чтения file2
и сохранения его содержимого. (шаблоны, которые вы хотите удалить изfile
)в массиве. Как и ответ Иниана, он читается как file1
. Для каждой строки в file1
он перебирает шаблоны из file2
. Мы предполагаем, что линия в порядке; если он соответствует какому-либо образцу, то это не нормально. Если после проверки всех шаблонов все еще в порядке, мы печатаем его.
Но я поставил FS=","
как аргумент между file2
и file1
просто потому, что так поступил Иниан. Неважно, какой разделитель f поля s мы используем, когда читаем file2
, до тех пор, пока он там не появляется — и file2
не содержит запятых. Таким образом, мы могли бы немного упростить вышеизложенное указав разделитель полей «обычным» способом — с опцией -F
в начале команды:
awk -F, 'FNR == NR { neg[$1]; next } { ok=1; for (i in neg) if ($2 ~ i) ok=0; if (ok) print }' file2 file1
Вы можете использовать -F","
, если хотите; они эквивалентны.
Тест FNR == NR
настолько популярен и распространен что мы используем его, не задумываясь. FNR
— это номер строки (, также известный как номер записи)в текущем файле, а NR
— это номер строки для всех входных данных. Так, например,
$ cat cats
Felix
Garfield
Heathcliff
$ cat dogs
Lassie
Marmaduke
Snoopy
$ awk '{ print FNR, NR, $0 }' cats dogs
1 1 Felix
2 2 Garfield
3 3 Heathcliff
1 4 Lassie
2 5 Marmaduke
3 6 Snoopy
… и поэтому FNR
и NR
равны для каждой строки первого обрабатываемого файла, а не в последующем файле (s ). Итак, мы используем FNR == NR
, чтобы проверить, обрабатываем ли мы первый файл.
Но на самом деле это плохая практика. Что делать, если первый файл пуст?
$ cat unicorns
$ wc unicorns
0 0 0 unicorns
$ awk '{ print FNR, NR, $0 }' unicorns dogs
1 1 Lassie
2 2 Marmaduke
3 3 Snoopy
FNR == NR
верно для первого файла , в котором действительно есть данные . Если твой file2
никогда не будет пустым, вы можете уйти, игнорируя эту проблему. Но, исходя из определения вашей проблемы, если file2
пусто, вывод должен быть весь из file1
, потому что мы ничего не удаляем. Но если вы запустите приведенную выше команду с пустым file2
, вы получите без вывода, потому что awk
думает, что читает первый файл (file2
) когда он на самом деле читает второй файл (file1
).
Более безопасный способ сделать это — поместить присваивание между аргументами файла:
awk -F, 'FILE != 2 { neg[$1]; next } { ok=1; for (i in neg) if ($2 ~ i) ok=0; if (ok) print }' file2 FILE=2 file1
Вопрос немного двусмысленный. Что означает «частичное совпадение», точно ? Иниан решил интерпретировать это в том смысле, что вопрос предполагает — вроде grep
. Если любое значение из file2
соответствует значению из второго столбца file1
как регулярное выражение, затем удалите эту строку file1
. Но есть две проблемы с этим.
Фактор неожиданности. Я взял файлы в вопросе и добавил
154376352,"http://sb288eco.tm","example4"
на file1
и выполнил свою первую команду. Эта строка "example4"
не выводилась, потому чтоsb288.co
(из file2
), взятое как регулярное выражение (, где.
означает «соответствует любому символу» ), соответствует sb288eco
.
Если вы этого хотите и ожидаете, Вы могли бы также перестать читать это сейчас.
Мы можем решить обе вышеуказанные проблемы проверив, является ли строка из file2
присутствует в значении из file1
с функцией awk index
:
awk -F, 'FILE != 2 { neg[$1]; next } { ok=1; for (i in neg) if (index($2,i) > 0) ok=0; if (ok) print }' file2 FILE=2 file1
С учетом вышеизложенного,.
в file2
соответствует только.
в file1
, а не любой другой персонаж. Я приглашаю вас проверить вышеизложенное на ваших данных и посмотреть, стало ли оно быстрее.
П.С. Я только что заметил, что вы изменили формат файла так как я опубликовал свой ответ. Изначально вы хотели проверить значения из file2
со значениями из второго столбца таблицы file1
. Теперь вы, кажется, хотите проверить со значениями изпервого столбцатаблицы file1
. Чтобы учесть это изменение, вы должны принять участие в любом из приведенных выше ответов который сравнивает $2
с i
и изменяет его, чтобы использовать вместо него $1
. Или, если вы действительно хотите проверить всю строку из file1
, используйте $0
.
Итак, вы можете использовать
awk -F, 'FILE != 2 { neg[$1]; next } { ok=1; for (i in neg) if (index($1,i) > 0) ok=0; if (ok) print }' file2 FILE=2 file1
по вашей команде. С разрывами строк для удобочитаемости это
awk -F, 'FILE != 2 { neg[$1]; next }
{
ok=1
for (i in neg)
if (index($1,i) > 0) ok=0
if (ok) print
}' \
file2 FILE=2 file1
То, что у вас есть, выглядит достойной попыткой, но пункт для соответствия регулярному выражению не работает так, как вы хотели. В $2 !~ neg[$1]
на file1
вы пытаетесь найти значение neg['156398439']
, потому что $1
будет получено из второго файла, а , а не из первого. Так что ваше состояние никогда не будет соответствовать.
Вы можете сделать что-то вроде приведенного ниже, где вы выполняете сравнение регулярных выражений внутри части действия на file1
с помощью цикла
awk 'FNR == NR { neg[$1]; next }{ for ( i in neg ) if ( $2 !~ i) print }' file2 FS="," file1
Также я не думаю, что FS
можно использовать такое сложное регулярное выражение для -ограничения CSV-файлов, помните, что FS
определяет, на какой -ограничитель разбиваться, а не на то, как определять поля. Кажется, у вас было выражение, объясняющее, как должно выглядеть поле. GNU awk
позволяет другой переменной FPAT
определять такое регулярное выражение.
Вы можете использовать
awk 'FNR == NR { neg[$1]; next }{ for ( i in neg ) if ( $2 !~ i) print }' file2 FPAT='([^,]*)|("[^"]+")' file1