ฉันจะเรียกคืนgrep
ไดเรกทอรีและไดเรกทอรีย่อยทั้งหมดซ้ำได้อย่างไร
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
ใช้ไม่ได้กับ Redhat Linux ฉันได้รับข้อผิดพลาด "ไม่ตรงกัน"
ฉันจะเรียกคืนgrep
ไดเรกทอรีและไดเรกทอรีย่อยทั้งหมดซ้ำได้อย่างไร
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
ใช้ไม่ได้กับ Redhat Linux ฉันได้รับข้อผิดพลาด "ไม่ตรงกัน"
คำตอบ:
grep -r "texthere" .
พารามิเตอร์แรกแสดงถึงนิพจน์ทั่วไปที่ต้องการค้นหาในขณะที่พารามิเตอร์ที่สองแสดงถึงไดเรกทอรีที่ควรค้นหา ในกรณีนี้.
หมายถึงไดเรกทอรีปัจจุบัน
หมายเหตุ: สิ่งนี้ใช้ได้กับ GNU grep และในบางแพลตฟอร์มเช่น Solaris คุณต้องใช้ grep GNU โดยเฉพาะเมื่อเทียบกับการใช้งานแบบดั้งเดิม สำหรับ Solaris นี่คือggrep
คำสั่ง
AIX 5.3
ตัวอย่าง
หากคุณรู้นามสกุลหรือรูปแบบของไฟล์ที่คุณต้องการวิธีอื่นคือการใช้--include
ตัวเลือก:
grep -r --include "*.txt" texthere .
--exclude
นอกจากนี้คุณยังสามารถพูดถึงไฟล์ที่จะไม่รวมกับ
หากคุณค้นหารหัสบ่อยๆAg (The Silver Searcher)เป็นทางเลือกที่รวดเร็วกว่า grep มากซึ่งเป็นรหัสที่กำหนดเองสำหรับการค้นหา ตัวอย่างเช่นมันเรียกซ้ำโดยค่าเริ่มต้นและจะไม่สนใจไฟล์และไดเรกทอรีที่อยู่ในรายการโดยอัตโนมัติ.gitignore
ดังนั้นคุณไม่จำเป็นต้องผ่านตัวเลือกที่ไม่ยุ่งยากเช่นเดียวกับ grep หรือค้นหา
=
ทำงานได้ดีบน Ubuntu PS: ที่ควรจะเป็นพื้นที่ backticked แต่ตัวแยกวิเคราะห์ SO markdown ล้มเหลว
grep
, ไม่ได้สำหรับ Ag เพียงเพื่อให้คุณรู้ :)
--include "*.txt" --include "*.TXT"
นอกจากนี้:
find ./ -type f -print0 | xargs -0 grep "foo"
แต่grep -r
เป็นคำตอบที่ดีกว่า
find . -type f -exec grep "foo" '{}' \;
ทำงานได้ดีที่สนับสนุน
find ./ -type f -print0 | xargs -0 grep "foo"
ตอนนี้ฉันมักจะใช้ (แม้ใน Windows ด้วยGoW - Gnu บน Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
ซึ่งรวมถึงตัวเลือกต่อไปนี้:
--include=PATTERN
recurse
PATTERN
ในไดเรกทอรีเท่านั้นค้นหาไฟล์ที่ตรงกัน
-n, --line-number
นำหน้าแต่ละบรรทัดของเอาต์พุตด้วยหมายเลขบรรทัดภายในไฟล์อินพุต
(หมายเหตุ: phuclvเพิ่มในความคิดเห็นที่ -n
ลดประสิทธิภาพมากดังนั้นคุณอาจต้องการข้ามตัวเลือกนั้น)
-R, -r, --recursive
อ่านไฟล์ทั้งหมดภายใต้แต่ละไดเรกทอรีซ้ำ; นี่เท่ากับ
-d recurse
ตัวเลือก
-H, --with-filename
พิมพ์ชื่อไฟล์สำหรับการแข่งขันแต่ละครั้ง
-I
ประมวลผลไฟล์ไบนารีราวกับว่ามันไม่มีข้อมูลที่ตรงกัน
นี่เท่ากับ--binary-files=without-match
ตัวเลือก
และฉันสามารถเพิ่ม ' i
' ( -nRHIi
) ถ้าฉันต้องการผลลัพธ์ที่ไม่ตรงตามตัวพิมพ์ใหญ่ - เล็ก
ฉันจะได้รับ:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
-R
ตัวเลือก) กับโฟลเดอร์
*
หรือ.
เป็นรูปแบบ glob (ตีความโดยเปลือก): unix.stackexchange.com/a/64695/7490 ' .
' จะเลือก dotfiles หรือจุดโฟลเดอร์เช่นกัน (เหมือน.git/
)
grep -rnI
แต่จากนั้นฉันได้เรียนรู้ว่า-n
ประสิทธิภาพลดลงมากดังนั้นฉันจึงใช้เมื่อต้องการจริงๆและโดยปกติฉันจะใช้-rI
ในระบบ POSIX คุณจะไม่พบ-r
พารามิเตอร์สำหรับgrep
และgrep -rn "stuff" .
จะไม่ทำงาน แต่ถ้าคุณใช้find
คำสั่งมันจะ:
find . -type f -exec grep -n "stuff" {} \; -print
เห็นด้วยและSolaris
HP-UX
-exec
ตัวเลือก - สัญลักษณ์{}
คือการอ้างอิงไปยังชื่อไฟล์ซึ่งปัจจุบันพบโดยfind
เครื่องมือ (นั่นคือการทำอะไรกับชื่อไฟล์ที่เราพบ) -exec
ตัวเลือกควรจะสิ้นสุดด้วย;
สัญลักษณ์ (เพื่อทำเครื่องหมายจุดสิ้นสุดของคำสั่ง exec) แต่เพราะนี่คือทั้งหมด ทำงานในเปลือกที่สัญลักษณ์ควรจะหนี .. และสุดท้าย-print
ตัวเลือกช่วยให้find
เครื่องมือในการพิมพ์ชื่อไฟล์ที่พบบนหน้าจอ
**
การใช้grep -r
งาน แต่อาจมากเกินไปโดยเฉพาะในโฟลเดอร์ขนาดใหญ่
สำหรับการใช้งานจริงยิ่งขึ้นนี่คือไวยากรณ์ที่ใช้globbing syntax ( **
):
grep "texthere" **/*.txt
ซึ่ง greps เฉพาะไฟล์ที่มีรูปแบบที่เลือกรูปแบบ การทำงานสำหรับเปลือกหอยที่สนับสนุนเช่นทุบตีที่ 4หรือzsh
shopt -s globstar
เพื่อเปิดใช้งานคุณลักษณะนี้ทำงาน:
ดูเพิ่มเติม: ฉันจะค้นหาไฟล์ทั้งหมดที่มีข้อความเฉพาะบน Linux ได้อย่างไร
git grep
สำหรับโครงการภายใต้การควบคุมเวอร์ชัน Git ให้ใช้:
git grep "pattern"
ซึ่งเร็วกว่ามาก
ripgrep
สำหรับโครงการขนาดใหญ่เครื่องมือ grepping ที่เร็วที่สุดคือripgrep
ไฟล์ greps ที่เรียกซ้ำโดยค่าเริ่มต้น:
rg "pattern" .
มันถูกสร้างขึ้นจากเครื่องมือ regex ของ Rustซึ่งใช้ออโต้ไฟน์ จำกัด , SIMD และการเพิ่มประสิทธิภาพตัวอักษรที่ก้าวร้าวเพื่อให้การค้นหารวดเร็วมาก ตรวจสอบการวิเคราะห์รายละเอียดที่นี่
เพื่อหาชื่อของfiles
ด้วยpath
ซ้ำที่มีโดยเฉพาะอย่างยิ่งstring
การใช้งานดังต่อไปนี้คำสั่งสำหรับUNIX
:
find . | xargs grep "searched-string"
สำหรับLinux
:
grep -r "searched-string" .
ค้นหาไฟล์บนUNIX
เซิร์ฟเวอร์
find . -type f -name file_name
ค้นหาไฟล์บนเซิร์ฟเวอร์ LINUX
find . -name file_name
เพียงชื่อไฟล์ก็มีประโยชน์เช่นกัน
grep -r -l "foo" .
หากคุณต้องการติดตามเฉพาะไดเรกทอรีจริงไม่ใช่ลิงก์สัญลักษณ์
grep -r "thingToBeFound" directory
หากคุณต้องการติดตามลิงก์สัญลักษณ์รวมถึงไดเรกทอรีจริง (โปรดระวังการเรียกซ้ำแบบไม่สิ้นสุด)
grep -R "thing to be found" directory
เนื่องจากคุณพยายาม grep ซ้ำตัวเลือกต่อไปนี้อาจเป็นประโยชน์กับคุณ:
-H: outputs the filename with the line
-n: outputs the line number in the file
ดังนั้นหากคุณต้องการค้นหาไฟล์ทั้งหมดที่มี Darth Vader ในไดเรกทอรีปัจจุบันหรือไดเรกทอรีย่อยใด ๆ และจับชื่อไฟล์และหมายเลขบรรทัด แต่ไม่ต้องการให้ recursion ติดตามลิงก์สัญลักษณ์คำสั่งจะเป็น
grep -rnH "Darth Vader" .
หากคุณต้องการค้นหาคำทั้งหมดที่กล่าวถึง cat ในไดเรคทอรี
/home/adam/Desktop/TomAndJerry
และขณะนี้คุณอยู่ในไดเรกทอรี
/home/adam/Desktop/WorldDominationPlot
และคุณต้องการจับชื่อไฟล์ แต่ไม่ใช่หมายเลขบรรทัดของอินสแตนซ์ใด ๆ ของสตริง "cats" และคุณต้องการให้ recursion ติดตามลิงก์สัญลักษณ์หากพบพวกเขาคุณสามารถเรียกใช้อย่างใดอย่างหนึ่งต่อไปนี้
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
ที่มา:
ใช้งาน "grep --help"
คำแนะนำสั้น ๆ เกี่ยวกับลิงก์สัญลักษณ์สำหรับทุกคนที่อ่านคำตอบนี้และสับสนโดยการอ้างอิงของฉันถึงพวกเขา: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag เป็นวิธีที่ชื่นชอบการทำเช่นนี้ในขณะนี้github.com/ggreer/the_silver_searcher มันเป็นพื้นเดียวกันกับแอ๊ แต่มีการเพิ่มประสิทธิภาพอีกสองสาม
นี่คือมาตรฐานสั้น ๆ ฉันล้างแคชก่อนการทดสอบแต่ละครั้ง (cf /ubuntu/155768/how-do-i-clean-or-disable-the-memory-cache ) cf
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
สิ่งนี้น่าจะใช้ได้:
grep -R "texthere" *
หากคุณกำลังมองหาเนื้อหาเฉพาะในไฟล์ทั้งหมดจากโครงสร้างไดเรกทอรีคุณอาจใช้find
เนื่องจากมีความชัดเจนมากขึ้นว่าคุณกำลังทำอะไรอยู่:
find -type f -exec grep -l "texthere" {} +
โปรดทราบว่า-l
(ตัวพิมพ์เล็กของ L) แสดงชื่อของไฟล์ที่มีข้อความ ลบออกหากคุณต้องการพิมพ์การแข่งขันแทน หรือใช้-H
เพื่อรับไฟล์พร้อมกับการแข่งขัน ทั้งหมดเข้าด้วยกันทางเลือกอื่น ๆ :
find -type f -exec grep -Hn "texthere" {} +
ที่ไหน-n
พิมพ์หมายเลขบรรทัด
find
ทางออกเดียวที่หลีกเลี่ยงการใช้งานโดยไม่จำเป็นxargs
และ+
แทนที่จะใช้\;
ด้วย-exec
ดังนั้นจึงหลีกเลี่ยงการเปิดตัวกระบวนการที่ไม่จำเป็นจำนวนมาก :-)
นี่คือสิ่งที่ทำงานกับเคสของฉันบนเครื่องปัจจุบันของฉัน (git bash บน windows 7)
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
ฉันมักจะลืม -print0 และ -0 สำหรับเส้นทางที่มีช่องว่าง
แก้ไข: เครื่องมือที่ต้องการของฉันตอนนี้แทน ripgrep: https://github.com/BurntSushi/ripgrep/releases มันเร็วมากและมีค่าเริ่มต้นที่ดีกว่า (เช่นเรียกซ้ำโดยปริยาย) ตัวอย่างเช่นเดียวกับคำตอบดั้งเดิมของฉัน แต่ใช้ ripgrep:rg -g "*.cs" "content pattern"
grep -r "texthere" .
(ระยะเวลาแจ้งให้ทราบในตอนท้าย)
(เครดิต ^: https://stackoverflow.com/a/1987928/1438029 )
ชี้แจง:
grep -r "texthere" /
(grep ไดเรกทอรีซ้ำทั้งหมดและไดเรกทอรีย่อย)
grep -r "texthere" .
(grep ไดเรกทอรีและไดเรกทอรีย่อยเหล่านี้ซ้ำ ๆ ซ้ำ ๆ)
grep [options] PATTERN [FILE...]
[ตัวเลือก]
-R, -r, --recursive
อ่านไฟล์ทั้งหมดภายใต้แต่ละไดเรกทอรีซ้ำ
สิ่งนี้เทียบเท่ากับ
-d recurse
หรือ--directories=recurse
ตัวเลือก
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
ในปีพ. ศ. 2561 คุณต้องการใช้งานripgrep
หรือthe-silver-searcher
เพราะเร็วกว่าทางเลือกอื่น
นี่คือไดเรกทอรีที่มีไดเรกทอรีย่อยระดับ 336:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
ใน OSX นี้ติดตั้ง:ripgrep
brew install ripgrep
การติดตั้งนี้silver-searcher
: brew install the_silver_searcher
.
rg
ก็มีข้อได้เปรียบเหนือกว่าการปูด้วยก้อนกรวดรวมกันเป็นคำสั่ง grep แบบเรียกซ้ำตั้งแต่เริ่มต้น ใช้rg
: rg foo
. find . | xargs grep foo
การใช้เครื่องมือยูนิกซ์: และถ้าใด ๆ find . -print0 | xargs -0 grep foo
ของไฟล์ของคุณมีคำพูดในนั้นคุณจำเป็นต้องใช้ คุณจะจำได้หรือไม่ว่าถ้าคุณใช้สิ่งนี้ปีละสองสามครั้ง?
find . -type f -exec grep 'regex' {} +
ซึ่งแน่นอนจำง่ายถ้าคุณใช้เครื่องมือเหล่านี้ด้วยความสม่ำเสมอ แต่อาจเป็นไปได้ว่าคุณควรรันctags
หรือetags
บนทรีซอร์สของคุณหากคุณต้องการค้นหาสิ่งต่างๆบ่อยครั้ง
ในเซิร์ฟเวอร์ IBM AIX ของฉัน (เวอร์ชัน OS: AIX 5.2) ให้ใช้:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
สิ่งนี้จะพิมพ์พา ธ / ชื่อไฟล์และหมายเลขบรรทัดสัมพัทธ์ในไฟล์เช่น:
./inc/xxxx_x.h
2865: / ** คำอธิบาย: stringYouWannaFind * /
อย่างไรก็ตามมันใช้งานได้สำหรับฉัน:)
ด้านล่างนี้เป็นคำสั่งสำหรับการค้นหาString
ซ้ำUnix
และLinux
สภาพแวดล้อม
สำหรับUNIX
คำสั่งคือ:
find . -name "string to be searched" -exec grep "text" "{}" \;
สำหรับLinux
คำสั่งคือ:
grep -r "string to be searched" .
สำหรับรายการของธงที่มีอยู่:
grep --help
ส่งคืนการจับคู่ทั้งหมดสำหรับtext regexp ในไดเรกทอรีปัจจุบันด้วยหมายเลขบรรทัดที่สอดคล้องกัน:
grep -rn "texthere" .
ส่งคืนการจับคู่ทั้งหมดสำหรับtexthereเริ่มต้นที่ไดเร็กทอรี root ด้วยหมายเลขบรรทัดที่สอดคล้องกันและไม่สนใจขนาดตัวพิมพ์:
grep -rni "texthere" /
ธงที่ใช้ที่นี่:
-r
recursive -n
พิมพ์หมายเลขบรรทัดพร้อมเอาต์พุต -i
ไม่สนใจกรณีฉันเดาว่านี่คือสิ่งที่คุณพยายามจะเขียน
grep myText $(find .)
และนี่อาจเป็นประโยชน์อย่างอื่นถ้าคุณต้องการค้นหาไฟล์ grep hit
grep myText $(find .) | cut -d : -f 1 | sort | uniq
ขว้างสองเซ็นต์ของฉันที่นี่ อย่างที่คนอื่นพูดถึงแล้วgrep -r ใช้ไม่ได้กับทุกแพลตฟอร์ม นี่อาจฟังดูไร้สาระ แต่ฉันมักจะใช้คอมไพล์
git grep "texthere"
แม้ว่าไดเรกทอรีจะไม่ถูกจัดฉากฉันแค่ทำมันและใช้ greit grep
โปรดทราบว่าfind . -type f | xargs grep whatever
การแก้ปัญหาประเภทต่างๆจะพบข้อผิดพลาด "รายการอาร์กิวเมนต์เป็นยาว" เมื่อมีไฟล์ที่ตรงกับการค้นหามากเกินไป
ทางออกที่ดีที่สุดคือgrep -r
แต่ถ้ายังไม่มีให้ใช้find . -type f -exec grep -H whatever {} \;
แทน
xargs
เป็นการแก้ปัญหาเฉพาะสำหรับปัญหา "รายการอาร์กิวเมนต์ยาวเกินไป"
find . -type f | xargs -L 100 grep whatever
xargs
ได้มาตรฐานเพื่อให้พฤติกรรมนี้ออกจากกล่อง " xargs
ยูทิลิตี้จะจำกัดความยาวบรรทัดคำสั่งเช่นนั้นเมื่อมีการเรียกใช้บรรทัดคำสั่งอาร์กิวเมนต์ที่รวมกันและรายการสภาพแวดล้อม ... จะต้องไม่เกิน {ARG_MAX} -2048 ไบต์"
เพียงเพื่อความสนุกการค้นหาไฟล์ * .txt ที่รวดเร็วและสกปรกหากคำตอบ @christangrant พิมพ์มากเกินไป :-)
grep -r texthere .|grep .txt
นี่คือฟังก์ชั่นแบบเรียกซ้ำ (ทดสอบเบา ๆ ด้วย bash และ sh) ที่สำรวจโฟลเดอร์ย่อยทั้งหมดของโฟลเดอร์ที่กำหนด ($ 1) และใช้grep
การค้นหาสตริงที่กำหนด ($ 3) ในไฟล์ที่กำหนด ($ 2):
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
ใช้มันและตัวอย่างผลลัพธ์:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename
The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .