วิธีการตรวจสอบว่าไฟล์มีสตริงที่ระบุโดยใช้ Bash


266

ฉันต้องการตรวจสอบว่าไฟล์มีสตริงเฉพาะหรือไม่ในทุบตี ฉันใช้สคริปต์นี้ แต่มันไม่ทำงาน:

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

มีอะไรผิดปกติในรหัสของฉัน


2
คล้ายกับstackoverflow.com/questions/4749330/…
Pawel

นี่คือวิธีการ grep ผลลัพธ์ของcommand: stackoverflow.com/questions/12375722/…
rogerdpack

คำตอบ:


466
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 ใน exitcode นั่นหมายความว่าเงื่อนไขเป็นจริง เท็จอย่างอื่น

$ 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เพื่อปรับปรุงประสิทธิภาพการสแกน ส่งคืนเมื่อเกิดครั้งแรก
AlikElzin-kilaka

1
หากSomeStringมีอักขระพิเศษ regex (เช่น.) คุณอาจได้ผลลัพธ์ที่ไม่คาดคิด มันปลอดภัยกว่าที่จะใช้fgrep(หรือgrep -F) (เว้นแต่คุณต้องการ regex จริง ๆ ซึ่งในกรณีนี้egrep(หรือgrep -E) น่าจะเป็นตัวเลือกที่ดีที่สุด)
Walter Tross

ตัวอย่างifตัวอย่างไม่ถูกต้องเนื่องจากจะตรวจสอบว่ารหัสออกไม่ใช่ -0 เท่านั้น หากมีข้อผิดพลาดเกิดขึ้นเช่นไม่สามารถอ่านไฟล์ได้รหัสการออกจะไม่ใช่ 0 ดังนั้นคุณต้องทำสิ่งที่ชอบec=$?และตรวจสอบว่ามัน0(พบ) แล้วถ้ามัน1(ไม่พบ) และถ้ามันเป็นอย่างอื่น (ล้มเหลว)
ddekany

40

นอกเหนือจากคำตอบอื่น ๆ ซึ่งบอกวิธีการทำสิ่งที่คุณต้องการฉันพยายามอธิบายสิ่งที่ผิด (ซึ่งเป็นสิ่งที่คุณต้องการ

ใน Bash ifจะต้องปฏิบัติตามคำสั่ง หากรหัสทางออกของคำสั่งนี้มีค่าเท่ากับ 0 ดังนั้นthenจะดำเนินการelseส่วนหนึ่งส่วนอื่น ๆหากมีการดำเนินการใด ๆ

คุณสามารถทำได้ด้วยคำสั่งใด ๆ ตามที่อธิบายไว้ในคำตอบอื่น ๆ : if /bin/true; then ...; fi

[[เป็นคำสั่ง bash ภายในที่ใช้สำหรับการทดสอบบางอย่างเช่นการมีอยู่ของไฟล์การเปรียบเทียบตัวแปร ในทำนองเดียวกัน[เป็นคำสั่งภายนอก (มันตั้งอยู่โดยทั่วไปใน/usr/bin/[) ที่ดำเนินการประมาณการทดสอบเหมือนกัน แต่ความต้องการ]เป็นอาร์กิวเมนต์สุดท้ายซึ่งเป็นเหตุผลที่จะต้องมีเบาะด้วยช่องว่างด้านซ้ายซึ่งไม่ได้เป็นกรณีที่มี]]]

ที่นี่คุณไม่จำเป็นต้องมิได้[[[

อีกสิ่งหนึ่งคือวิธีที่คุณพูดสิ่งต่างๆ "$(command "argument")"ในทุบตีมีเพียงหนึ่งกรณีที่คู่ของคำพูดที่ทำรังมันเป็น แต่ใน'grep 'SomeString' $File'คุณมีเพียงหนึ่งคำเพราะ'grep 'เป็นหน่วยที่ยกมาซึ่งเป็น concatenated ด้วยแล้วตัดแบ่งอีกครั้งกับ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
การเปลี่ยนไดเรกทอรีมักไม่ใช่ความคิดที่ดี (และไม่จำเป็นโดยสิ้นเชิงที่นี่เพียงแค่รับรองชื่อไฟล์ด้วยไดเรกทอรีเป้าหมาย) แล้วสิ่งที่คุณมีก็เหมือนกับคำตอบที่ได้รับการยอมรับเท่านั้นโดยมีรายละเอียดน้อยกว่า
Mat

ขอบคุณสำหรับคำแนะนำ Mat
Nevin Raj Victor

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. ไม่มีเหตุผลมายุ่งกับ$?อะไรเลย
Charles Duffy

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(จริง) หากพบรูปแบบ สตริงว่างมิฉะนั้น



2

ลองสิ่งนี้:

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

3
ฉันลังเลที่จะงดเว้นการ downvoting นี้ แต่ Stack Overflow ไม่ควรยืดเยื้อตรรกะเพรทเซลประเภทนี้ grepส่งคืนสถานะการออกด้วยเหตุผลที่ดีมาก การจับเอาท์พุทลงในสายอักขระนั้นอาจจะเก็บข้อความจำนวนมากไว้ในบัฟเฟอร์เพื่อให้คุณบอกได้ว่ามันไม่ว่างเปล่า
tripleee

-1

ฉันทำสิ่งนี้ดูเหมือนว่าจะทำงานได้ดี

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

quoting เสียgrepและคุณอาจต้องการที่จะหลีกเลี่ยงการเห็นผลลัพธ์จาก
tripleee

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

1
คุณพิมพ์ผิด -! ควรจะเป็น $?
lzap

... ไม่เพียง แต่ตั้งใจจะให้เป็น$?เท่านั้น แต่ไม่จำเป็นต้องทำเลย - คุณสามารถทำได้if grep -q ...
Charles Duffy

1
นอกจากนี้foo && truthy_action || falsey_actionไม่ได้เป็นผู้ประกอบการจริงประกอบไปด้วย - ถ้าtruthy_actionล้มเหลวแล้วfalsey_actionได้รับการทำงานนอกเหนือ
Charles Duffy

โดยทั่วไปแล้ววัตถุประสงค์ของifการเรียกใช้คำสั่งและตรวจสอบรหัสออก คุณไม่ค่อยจำเป็นต้องตรวจสอบ$?อย่างชัดเจน
tripleee
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.