Cách kiểm tra xem một tệp có chứa một chuỗi cụ thể bằng Bash không


266

Tôi muốn kiểm tra xem một tập tin có chứa một chuỗi cụ thể hay không trong bash. Tôi đã sử dụng tập lệnh này, nhưng nó không hoạt động:

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

Có gì sai trong mã của tôi?



Dưới đây là cách grep đầu ra của a command: stackoverflow.com/questions/12375722/ cấp
rogerdpack

Câu trả lời:


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

Bạn không cần [[ ]]ở đây. Chỉ cần chạy lệnh trực tiếp. Thêm -qtùy chọn khi bạn không cần chuỗi hiển thị khi nó được tìm thấy.

Các greplệnh trả về 0 hoặc 1 trong các mã thoát tùy thuộc vào kết quả tìm kiếm. 0 nếu một cái gì đó được tìm thấy; 1 khác.

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

Bạn có thể chỉ định các lệnh như là một điều kiện của if. Nếu lệnh trả về 0 trong mã thoát của nó, điều đó có nghĩa là điều kiện này là đúng; nếu không thì sai.

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

Như bạn có thể thấy bạn chạy ở đây các chương trình trực tiếp. Không bổ sung []hoặc [[]].


Thông tin thêm về grepvà các tùy chọn có sẵn trong asnwer stackoverflow.com/a/4749368/1702557
Pawel

2
có thể muốn xem xét -Fxqcác tham số như trong stackoverflow.com/a/4749368/544721
Grzegorz Wierzowiecki

3
xem xét sử dụng -m 1để cải thiện hiệu suất quét. Trả về lần xuất hiện đầu tiên.
AlikElzin-kilaka

1
nếu SomeStringchứa các ký tự đặc biệt regex (như .), bạn có thể nhận được kết quả không mong muốn. An toàn hơn khi luôn sử dụng fgrep(hoặc grep -F) (trừ khi bạn thực sự cần regex, trong trường hợp đó egrep(hoặc grep -E) có lẽ là lựa chọn tốt nhất)
Walter Tross

Ví dụ ví ifdụ không chính xác, vì nó chỉ kiểm tra xem mã thoát có khác không không. Nếu có bất kỳ lỗi nào xảy ra, như tệp không thể đọc được, mã thoát cũng không phải là 0. Vì vậy, bạn phải làm một cái gì đó như ec=$?, và kiểm tra xem nó 0(tìm thấy), sau đó nếu nó 1(không tìm thấy), và sau đó nếu một cái gì đó khác (thất bại).
ddekany

40

Ngoài các câu trả lời khác, cho bạn biết làm thế nào để làm những gì bạn muốn, tôi cố gắng giải thích những gì sai (đó là những gì bạn muốn.

Trong Bash, ifđược tuân theo một lệnh. Nếu mã thoát của lệnh này bằng 0, thì thenphần đó được thực thi, elsephần khác nếu có được thực thi.

Bạn có thể làm điều đó với bất kỳ lệnh nào như được giải thích trong các câu trả lời khác: if /bin/true; then ...; fi

[[là một lệnh bash nội bộ dành riêng cho một số thử nghiệm, như sự tồn tại của tệp, so sánh biến. Tương tự [là một lệnh bên ngoài (thường được đặt trong /usr/bin/[) thực hiện các phép thử gần giống nhau nhưng cần ]làm đối số cuối cùng, đó là lý do tại sao ]phải được đệm bằng một khoảng trắng ở bên trái, không phải là trường hợp với ]].

Ở đây bạn không cần [[cũng không [.

Một điều nữa là cách bạn trích dẫn mọi thứ. Trong bash, chỉ có một trường hợp mà các cặp trích dẫn làm tổ, đó là "$(command "argument")". Nhưng trong 'grep 'SomeString' $File'bạn chỉ có một từ, bởi vì 'grep 'là một đơn vị được trích dẫn, được nối với SomeStringvà sau đó lại được nối với ' $File'. Biến $Filethậm chí không được thay thế bằng giá trị của nó do sử dụng dấu ngoặc đơn. Cách thích hợp để làm điều đó là grep 'SomeString' "$File".


15

Trong trường hợp nếu bạn muốn kiểm tra xem tập tin không chứa một chuỗi cụ thể, bạn có thể làm như sau.

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
Thay đổi thư mục thường không phải là một ý tưởng tốt (và hoàn toàn không cần thiết ở đây, chỉ cần đủ điều kiện tên tệp với thư mục đích). Và sau đó, những gì bạn có chính xác giống như câu trả lời được chấp nhận, chỉ với ít chi tiết hơn.
Mat

Cảm ơn lời khuyên Mat
Nevin Raj Victor

7

Phiên bản ngắn nhất (chính xác):

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

cũng có thể được viết là

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

nhưng bạn không cần phải kiểm tra nó một cách rõ ràng trong trường hợp này, do đó, tương tự với:

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

3
if grep -q something file; then echo yes; else echo no; fi. Không có lý do để gây rối với $?tất cả.
Charles Duffy

6

Trong trường hợp bạn muốn kiểm tra xem chuỗi có khớp với toàn bộ dòng không và nếu đó là một chuỗi cố định, Bạn có thể thực hiện theo cách này

grep -Fxq [String] [filePath]

thí dụ

 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

Từ tập tin người đàn ông:

-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 $?

Trạng thái thoát là 0(đúng) nếu mẫu được tìm thấy; nếu không thì dây trống.


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

Thí dụ

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

2

Thử cái này:

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

3
Tôi ngần ngại từ chối việc hạ thấp điều này, nhưng Stack Overflow không nên duy trì loại logic bánh quy cây này. greptrả về một trạng thái thoát vì một lý do rất tốt; Việc bắt đầu ra thành một chuỗi có khả năng sẽ lưu trữ một lượng lớn văn bản trong một bộ đệm để bạn có thể nói nó không trống.
tripleee

-1

Tôi đã làm điều này, dường như làm việc tốt

if grep $SearchTerm $FileToSearch; then
   echo "$SearchTerm found OK"
else
   echo "$SearchTerm not found"
fi

Các trích dẫn bị hỏng , và bạn có thể muốn tránh nhìn thấy đầu ra từ grep.
tripleee

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

1
Bạn có một lỗi đánh máy -!? được cho là $?
lzap

... không chỉ có ý định $?, mà còn không cần nó - bạn chỉ có thể làmif grep -q ...
Charles Duffy

1
Hơn nữa, foo && truthy_action || falsey_actionkhông phải là một nhà điều hành ternary thực - nếu truthy_actionthất bại, sau đó falsey_actionđược chạy ngoài .
Charles Duffy

Tổng quát hơn, mục đích của iflà chạy một lệnh và kiểm tra mã thoát của nó. Bạn rất hiếm khi cần phải kiểm tra $?rõ ràng.
tripleee
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.