Як перевірити, чи містить файл певний рядок за допомогою Bash


265

Я хочу перевірити, чи файл містить певний рядок чи ні в bash. Я використовував цей сценарій, але він не працює:

 if [[ 'grep 'SomeString' $File' ]];then
   # Some Actions
 fi

Що не так у моєму коді?



Ось як Grep вихідних даних command: stackoverflow.com/questions/12375722 / ...
rogerdpack

Відповіді:


465
if grep -q SomeString "$File"; then
  Some Actions # SomeString was found
fi

Вам тут не потрібно [[ ]]. Просто запустіть команду безпосередньо. Додайте -qопцію, коли рядок не відображається, коли вона знайдена.

grepКоманда повертає 0 або 1 в коді виходу в залежності від результату пошуку. 0 якщо щось було знайдено; 1 інакше.

$ echo hello | grep hi ; echo $?
1
$ echo hello | grep he ; echo $?
hello
0
$ echo hello | grep -q he ; echo $?
0

Ви можете вказати команди як умову if. Якщо команда повертає 0 у своєму вихідному коді, це означає, що умова справжня; інакше помилково.

$ if /bin/true; then echo that is true; fi
that is true
$ if /bin/false; then echo that is true; fi
$

Як бачите, ви запускаєте тут програми безпосередньо. Ніякої додатковий []або [[]].


Більш детальна інформація про grepта доступні варіанти в asnwer stackoverflow.com/a/4749368/1702557
Pawel

2
можливо , захочете розглянути -Fxqпараметри , як stackoverflow.com/a/4749368/544721
Grzegorz Wierzowiecki

3
Подумайте про використання -m 1для підвищення продуктивності сканування. Повертається при першій появі.
АлікЕльзін-кілака

1
якщо SomeStringмістять спеціальні символи регулярного вираження (наприклад .), ви можете отримати несподівані результати. Безпечніше завжди використовувати fgrep(або grep -F) (якщо вам справді не потрібен регулярний вираз, в такому випадку egrep(або grep -E) це, мабуть, найкращий вибір)
Уолтер Трос

Приклад ifприкладу є невірним, оскільки він перевіряє, чи не був код виходу 0. Якщо будь-яка помилка, наприклад, файл не може бути прочитаний, вихідний код також не-0. Отже, ви повинні зробити щось на кшталт ec=$?і перевірити, чи це 0(знайдено), потім, якщо це 1(не знайдено), а потім, якщо це щось інше (не вдалося).
декани

40

Окрім інших відповідей, які розповідали, як робити те, що ти хотів, я намагаюся пояснити, що було не так (а що ти хотів.

У Bash ifслід виконувати команду. Якщо вихідний код цієї команди дорівнює 0, то thenчастина виконується, інакше elseчастина, якщо така виконується.

Це можна зробити за допомогою будь-якої команди, як пояснено в інших відповідях: if /bin/true; then ...; fi

[[це внутрішня команда bash, яка присвячена деяким тестам, наприклад, існуванню файлів, змінним порівнянням. Аналогічно [це зовнішня команда (вона розташована, як правило, в /usr/bin/[), яка виконує приблизно ті ж тести, але потребує ]остаточного аргументу, і саме тому ]необхідно забити пробіл ліворуч, з чим це не так ]].

Тут вам не потрібно [[ні [.

Інша справа, як ви цитуєте речі. У баші, є лише один випадок, коли пари цитат гніздяться, це "$(command "argument")". Але у 'grep 'SomeString' $File'вас є лише одне слово, тому що 'grep 'це цитується одиниця, яка об'єднується з, SomeStringа потім знову конкатенована ' $File'. Змінна $Fileнавіть не замінюється своїм значенням через використання одиничних лапок. Правильний спосіб це зробити grep 'SomeString' "$File".


15

Якщо ви хочете перевірити, чи не містить файл певний рядок, ви можете зробити це наступним чином.

if ! grep -q SomeString "$File"; then
  Some Actions # SomeString was not found
fi

10
##To check for a particular  string in a file

cd PATH_TO_YOUR_DIRECTORY #Changing directory to your working directory
File=YOUR_FILENAME  
if grep -q STRING_YOU_ARE_CHECKING_FOR "$File"; ##note the space after the string you are searching for
then
echo "Hooray!!It's available"
else
echo "Oops!!Not available"
fi

2
Зміна каталогу, як правило, не є хорошою ідеєю (і тут абсолютно непотрібна, просто кваліфікуйте ім'я файлу з цільовим каталогом). І тоді у вас є те саме, що і прийнята відповідь, лише з меншими деталями.
Мат

Дякую за пораду Мат
Невін Радж Віктор

7

Найкоротша (правильна) версія:

grep -q "something" file; [ $? -eq 0 ] && echo "yes" || echo "no"

можна також записати як

grep -q "something" file; test $? -eq 0 && echo "yes" || echo "no"

але вам не потрібно явно тестувати це в цьому випадку, так що те саме:

grep -q "something" file && echo "yes" || echo "no"

3
if grep -q something file; then echo yes; else echo no; fi. Немає жодної причини возитися $?.
Чарльз Даффі

6

Якщо ви хочете перевірити рядок, що відповідає цілому рядку, і якщо це фіксований рядок, ви можете це зробити так

grep -Fxq [String] [filePath]

приклад

 searchString="Hello World"
 file="./test.log"
 if grep -Fxq "$searchString" $file
    then
            echo "String found in $file"
    else
            echo "String not found in $file"
 fi

З файлу 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.)

6
grep -q [PATTERN] [FILE] && echo $?

Статус виходу є 0(істинним), якщо шаблон знайдено; в іншому випадку пусті рядки.


4
if grep -q [string] [filename]
then
    [whatever action]
fi

Приклад

if grep -q 'my cat is in a tree' /tmp/cat.txt
then
    mkdir cat
fi

2

Спробуйте це:

if [[ $(grep "SomeString" $File) ]] ; then
   echo "Found"
else
   echo "Not Found"
fi

3
Я нерішуче ухиляюся від спростування цього, але Stack Overflow не повинен увічнювати таку логіку кренделів. grepповертає статус виходу з дуже поважної причини; захоплення виводу в рядок потенційно може зберігати велику кількість тексту в буфері, щоб ви могли сказати, що він не порожній.
tripleee


-3
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"

1
У вас помилка друку -!? повинен бути $?
lzap

... не тільки це призначено бути $?, але в цьому взагалі немає потреби - ви могли просто зробитиif grep -q ...
Чарльз Даффі

1
Більше того, foo && truthy_action || falsey_actionце не справжній потрійний оператор - якщо він truthy_actionне працює, то додатковоfalsey_action запускається .
Чарльз Даффі

В цілому, мета в ifце запустити команду і перевірити її код виходу. Вам слід дуже рідко потребувати $?явного огляду .
трійка
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.