Как проверить, существует ли строка в файле с Bash?
У меня есть файл, содержащий имена каталогов:
my_list.txt
:
/tmp
/var/tmp
Я хочу проверить Bash, прежде чем добавить имя каталога, если это имя уже существует в файле.
Ответы
Ответ 1
grep -Fxq "$FILENAME" my_list.txt
Статус выхода равен 0 (true), если имя найдено, 1 (false), если нет, поэтому:
if grep -Fxq "$FILENAME" my_list.txt
then
# code if found
else
# code if not found
fi
Объяснение
Вот соответствующие разделы страницы руководства для grep
:
grep [options] PATTERN [FILE...]
-F
, --fixed-strings
Интерпретировать 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 $?' in
0)
# code if found
;;
1)
# code if not found
;;
*)
# code if an error occurred
;;
esac
Ответ 2
Что касается следующего решения:
grep -Fxq "$FILENAME" my_list.txt
Если вам интересно (как и я), что означает -Fxq
на простом английском языке:
-
F
: влияет на интерпретацию PATTERN (фиксированная строка вместо регулярного выражения) -
x
: совпадение всей строки -
q
: Shhhhh... минимальная печать
Из файла 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.)
Ответ 3
Три метода в моем сознании:
1) Короткий тест для имени в пути (я не уверен, что это может быть ваш случай)
ls -a "path" | grep "name"
2) Короткий тест для строки в файле
grep -R "string" "filepath"
3) Дольше bash script с использованием регулярного выражения:
#!/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 content
then
echo "found"
else
echo "not found"
fi
exit
Это должно быть быстрее, если у вас есть , чтобы протестировать несколько строк в файле, используя цикл, например, изменяя регулярное выражение на любом cicle.
Ответ 4
Простейший способ:
if grep "$filename" my_list.txt > /dev/null
then
... found
else
... not found
fi
Совет: отправьте на /dev/null
, если вы хотите получить статус выхода, но не выходы.
Ответ 5
Самый простой и простой способ:
isInFile=$(cat file.txt | grep -c "string")
if [ $isInFile -eq 0 ]; then
#string not contained in file
else
#string is in file at least once
fi
grep -c вернет счет того, сколько раз строка в файле появляется.
Ответ 6
Если я правильно понял ваш вопрос, это должно сделать то, что вам нужно.
- вы можете указать каталог, который хотите добавить через переменную $check
- Если каталог уже находится в списке, на выходе будет указан "dir, уже указанный"
- Если каталог еще не указан в списке, он добавляется в файл my_list.txt
В одной строке: check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
Ответ 7
Если вы просто хотите проверить существование одной строки, вам не нужно создавать файл. Например,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ; then
# code for if it exists
else
# code for if it does not exist
fi
Ответ 8
Моя версия с использованием fgrep
FOUND=`fgrep -c "FOUND" $VALIDATION_FILE`
if [ $FOUND -eq 0 ]; then
echo "Not able to find"
else
echo "able to find"
fi
Ответ 9
grep -E "(string)" /path/to/file || echo "no match found"
Параметр -E позволяет использовать регулярные выражения grep
Ответ 10
Решение grep-less работает для меня:
MY_LIST=$( cat /path/to/my_list.txt )
if [[ "${MY_LIST}" == *"${NEW_DIRECTORY_NAME}"* ]]; then
echo "It there!"
else
echo "its not there"
fi
на основе:
fooobar.com/questions/833/...
Ответ 11
grep -Fxq "String to be found" | ls -a
- grep will поможет вам проверить содержимое
- ls перечислит все файлы
Ответ 12
if grep -q "$Filename$" my_list.txt
then
echo "exist"
else
echo "not exist"
fi