Интерпретировать PATTERN как список фиксированных строк, разделенных символами новой строки, любой из которых должен соответствовать.
-x, --line-regexp
Выберите только те совпадения, которые точно соответствуют всей строке.
-q, --quiet,--silent
Тихо; не пишите ничего в стандартный вывод. Выйдите немедленно с нулевым статусом, если найдено какое-либо совпадение, даже если обнаружена ошибка. Также смотрите опцию -sили --no-messages.
Обработка ошибок
Как справедливо указано в комментариях, вышеупомянутый подход молча обрабатывает случаи ошибок, как если бы строка была найдена. Если вы хотите обрабатывать ошибки другим способом, вам придется пропустить этот -qпараметр и обнаруживать ошибки на основе состояния выхода:
Обычно статус выхода равен 0, если выбранные строки найдены, и 1 в противном случае. Но состояние выхода равно 2, если произошла ошибка, если не используется опция -qили --quietили --silentи не найдена выбранная строка. Однако обратите внимание, что POSIX обязывает только для таких программ, как grep, cmpи diffчто состояние выхода в случае ошибки должно быть больше 1; поэтому для переносимости целесообразно использовать логику, которая проверяет это общее условие, вместо строгого равенства с 2.
Чтобы подавить нормальный вывод с grep, вы можете перенаправить его на /dev/null. Обратите внимание, что стандартная ошибка остается ненаправленной, поэтому любые сообщения об ошибках, которые grepмогут быть напечатаны, будут появляться на консоли, как вы, вероятно, захотите.
Для обработки трех случаев мы можем использовать caseинструкцию:
case`grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?`in0)# code if found;;1)# code if not found;;*)# code if an error occurred;;esac
Если я выполню эту команду из скрипта bash, как перехватить 0 или 1 в переменную?
Торен
6
@Toren К последнему состоянию выхода можно получить доступ с помощью $?. Вы также можете использовать команду grep вместе с ifоператором (как показано в обновленном ответе).
Шон Чин
5
Вы можете использовать, grep -Fqx "$FILENAME"и вам не нужно беспокоиться о регулярных выражениях в содержимом переменных, и вам не придется использовать их в строке поиска.
Приостановлено до дальнейшего уведомления.
4
Несколько замечаний для людей, которые смотрят на этот ответ: 1) В bash 0 всегда истинно, а все остальное всегда ложно 2) Используйте флаг -x, только если вы хотите, чтобы вся строка точно совпадала. Если вы просто хотите узнать, существует ли вообще ваша строка в файле, не указывайте это. Если вы хотите узнать, существует ли ваша строка точно, но не обязательно соответствует всей строке (т. Е. Как целое слово), используйте -w.
Шмик,
1
Я не понимаю, -q / --silentэто нужно? Это ложно говорит "все хорошо", чтобы bash, даже если происходит ошибка. Если я правильно понял. Кажется некорректной концепцией для этого случая.
redanimalwar
90
Относительно следующего решения:
grep -Fxq"$FILENAME" my_list.txt
Если вам интересно (как я это сделал), что -Fxqозначает на простом английском:
F: Влияет на интерпретацию PATTERN (фиксированная строка вместо регулярного выражения)
x: Соответствовать всей линии
q: Тссс ... минимальная печать
Из файла man:
-F,--fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.(-F is specified by POSIX.)-x,--line-regexp
Select only those matches that exactly match the whole line.(-x is specified by POSIX.)-q,--quiet,--silent
Quiet;do not write anything to standard output.Exit immediately with zero status if any match is
found, even if an error was detected.Also see the -s or --no-messages option.(-q is specified by
POSIX.)
-F не влияет на обработку файла, он влияет на интерпретацию PATTERN. Как правило, PATTERN интерпретируется как регулярное выражение, но с -F он будет интерпретироваться как фиксированная строка.
Адам С
41
Три метода в моей голове:
1) Короткий тест для имени в пути (я не уверен, что это может быть ваш случай)
ls -a "path"| grep "name"
2) Краткий тест для строки в файле
grep -R "string""filepath"
3) Более длинный скрипт bash с использованием регулярных выражений:
#!/bin/bash
declare file="content.txt"
declare regex="\s+string\s+"
declare file_content=$( cat "${file}")if[[" $file_content "=~ $regex ]]# please note the space before and after the file contentthen
echo "found"else
echo "not found"fi
exit
Это должно быть быстрее, если вам нужно протестировать несколько строк в содержимом файла, используя цикл, например, изменить регулярное выражение в любом цикле.
Вам не нужно проверять вывод grep, вы можете просто использовать grep -qи вызывать grep напрямую, ifкак это делает Томас в своем ответе. Кроме того, вопрос не включал проверку существования каталога до его добавления в список (в конце концов, это может быть список удаленных каталогов).
Сорпигал
Я удалил пример сценария, он ничего не добавил к ответу Томаса.
lecodesportif
3
Если вы просто хотите проверить наличие одной строки, вам не нужно создавать файл. Например,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ;then# code for if it existselse# code for if it does not existfi
Решение @ Thomas почему-то не сработало, но у меня была более длинная строка со специальными символами и пробелами, поэтому я просто изменил параметры следующим образом:
if grep -Fxq'string you want to find'"/path/to/file";then
echo "Found"else
echo "Not found"fi
Ответы:
Статус выхода равен 0 (true), если имя найдено, 1 (false), если нет, поэтому:
объяснение
Вот соответствующие разделы справочной страницы для
grep
:Обработка ошибок
Как справедливо указано в комментариях, вышеупомянутый подход молча обрабатывает случаи ошибок, как если бы строка была найдена. Если вы хотите обрабатывать ошибки другим способом, вам придется пропустить этот
-q
параметр и обнаруживать ошибки на основе состояния выхода:Чтобы подавить нормальный вывод с
grep
, вы можете перенаправить его на/dev/null
. Обратите внимание, что стандартная ошибка остается ненаправленной, поэтому любые сообщения об ошибках, которыеgrep
могут быть напечатаны, будут появляться на консоли, как вы, вероятно, захотите.Для обработки трех случаев мы можем использовать
case
инструкцию:источник
$?
. Вы также можете использовать команду grep вместе сif
оператором (как показано в обновленном ответе).grep -Fqx "$FILENAME"
и вам не нужно беспокоиться о регулярных выражениях в содержимом переменных, и вам не придется использовать их в строке поиска.-q / --silent
это нужно? Это ложно говорит "все хорошо", чтобы bash, даже если происходит ошибка. Если я правильно понял. Кажется некорректной концепцией для этого случая.Относительно следующего решения:
Если вам интересно (как я это сделал), что
-Fxq
означает на простом английском:F
: Влияет на интерпретацию PATTERN (фиксированная строка вместо регулярного выражения)x
: Соответствовать всей линииq
: Тссс ... минимальная печатьИз файла man:
источник
Три метода в моей голове:
1) Короткий тест для имени в пути (я не уверен, что это может быть ваш случай)
2) Краткий тест для строки в файле
3) Более длинный скрипт bash с использованием регулярных выражений:
Это должно быть быстрее, если вам нужно протестировать несколько строк в содержимом файла, используя цикл, например, изменить регулярное выражение в любом цикле.
источник
Более простой способ:
Подсказка: отправьте,
/dev/null
если хотите получить статус выхода команды, но не вывод.источник
-q
же самое, что и--quiet
:)-q
также лучший ответ здесь, и это четвертое место. нет справедливости в этом мире.Самый простой и простой способ будет:
grep -c вернет счетчик того, сколько раз строка встречается в файле.
источник
Если я правильно понял ваш вопрос, это должно сделать то, что вам нужно.
В одной строке :
check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
источник
grep -q
и вызывать grep напрямую,if
как это делает Томас в своем ответе. Кроме того, вопрос не включал проверку существования каталога до его добавления в список (в конце концов, это может быть список удаленных каталогов).Если вы просто хотите проверить наличие одной строки, вам не нужно создавать файл. Например,
источник
Моя версия с использованием fgrep
источник
-c
возможности вfgrep --help
-E опция заставляет grep использовать регулярные выражения
источник
Решение @ Thomas почему-то не сработало, но у меня была более длинная строка со специальными символами и пробелами, поэтому я просто изменил параметры следующим образом:
Надеюсь, это поможет кому-то
источник
Решение без grep, работает для меня:
на основании: https://stackoverflow.com/a/229606/3306354
источник
grep -q
Описанный в принятом ответе наиболее эффективный подход.источник
источник