grep для текста в строке. Но если комментарий есть только в начале, то исключите его из grep [duplicate]

Возможно, вы ищете шаблон

[a-z][a-z][0-9][0-9].txt

. Он будет соответствовать любому имени в текущем каталоге, состоящему ровно из двух символов нижнего регистра, за которыми следуют две цифры, за которыми следует буквенная строка . .txt.

Шаблоны подстановки имен файлов, в отличие от регулярных выражений, автоматически привязываются к началу и концу строки, поэтому нам не нужно говорить ничего особенного об именах файлов, не содержащих символы перед первым из двух символов нижнего регистра или после .txt.

Вы можете использовать этот шаблон с rm напрямую:

$ rm "$HOME"/[a-z][a-z][0-9][0-9].txt

или, если вы хотите выполнить рекурсию во все подкаталоги, с find:

$ find "$HOME" -name "[a-z][a-z][0-9][0-9].txt" -delete

Если ваша реализация найти не поддерживает -удалить, вместо этого рассмотрите следующее:

$ find "$HOME" -name "[a-z][a-z][0-9][0-9].txt" -exec rm {} +

PS: используйте слово цифра, когда вы имеете в виду число от нуля до девяти. число немного расплывчато, тем более что 233, которое является частью нескольких имен файлов в примерах, является числом. (С тех пор я отредактировал вопрос, чтобы устранить эту двусмысленность)

0
24.04.2018, 12:52
4 ответа

awk здесь будет лучшим выбором:

DB_NAME=test; export DB_NAME
file=$(awk -F: '$1 == ENVIRON["DB_NAME"] {print $2; exit}' < /etc/oratab)

printf '%s\n' "$file"

На Solaris обязательно выполните:

PATH=$(getconf PATH):$PATH

(и используйте #! /usr/xpg4/bin/sh -, если на Solaris 10 и старше ), чтобы иметь стандартные утилиты. Или используйте command -p awk. Иначе можно получить дедовский awkиз 70-х годов.

2
28.01.2020, 02:23

Гораздо более простым решением, чем -написать его для использования awk, будет добавление простого ^ для обозначения начала строки:

env_var=`cat /etc/oratab |grep $DB_NAME |grep -v '^#' |cut -d":" -f 2`

Команда grep -v '^#'удаляет все строки, начинающиеся с #, и часто бывает полезна.

1
28.01.2020, 02:23

С помощью sedвы можете комбинировать grepи cutза один проход:

sed "/^$DB_NAME:/! d;s///;s/:.*//" /etc/oratab

С

  • /^$DB_NAME:/выбирает все строки, начинающиеся с $DB_NAME, за которыми следует :; !инвертирует совпадение, поэтому следующее dудаляет все строки, которые не соответствуют этому шаблону
  • s///удаляет последнее совпадение, в данном случаеtest:
  • s/:.*//удаляет :и все последующие
0
28.01.2020, 02:23

Другие ответы подходят для примера (файл в формате CSV*(двоеточие -разделенные значения ), искомая строка -будет первым полем, желаемый результат - второе поле ), но ни одно из этих ограничений / условий на самом деле указано в вопросе. И, пока вопрос требует команды который исключает строки, которые начинаются с комментария, это, вероятно, не то, чего на самом деле хочет ОП. (Как насчет строки типа unwanted line:blah:blah #test, который содержитtestв комментарии ? )Ответ, который хочет ОП,

grep '^[^#]*test' /etc/oratab

или

grep "^[^#]*$DBNAME" /etc/oratab

, который ищет строку, где появляется test, и все символы перед ним не являются #.

Как обычно, ссылки на переменные оболочки всегда должны заключаться в кавычки. (например, "$DB_NAME"и "$env_var"), если у вас нет веских причин не делать этого, и вы уверены, что знаете, что делаете. И, , как указывает Стефан Шазела , если $DBNAMEвыглядит как не -тривиальное регулярное выражение (например, содержит ., *или []), возможны нежелательные результаты.

0
28.01.2020, 02:23

Теги

Похожие вопросы