ค้นหาและแทนที่ด้วย sed ในไดเรกทอรีและไดเรกทอรีย่อย


244

ฉันเรียกใช้คำสั่งนี้เพื่อค้นหาและแทนที่ 'apple' ด้วย 'ส้ม' ที่เกิดขึ้นในไฟล์ทั้งหมดในรูทของเว็บไซต์ของฉัน:

find ./ -exec sed -i 's/apple/orange/g' {} \;

แต่จะไม่ผ่านไดเรกทอรีย่อย

เกิดอะไรขึ้นกับคำสั่งนี้?

นี่คือผลลัพธ์บางส่วนของfind ./:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php

คุณสามารถเรียกใช้find ./และโพสต์ตัวอย่างผลลัพธ์ได้ไหม และโครงสร้างไดเรกทอรีโปรด แก้ไข: ขอบคุณ!
จาค็อบ

หืมมมการค้นหาของคุณถูกต้องใช้ได้กับฉันด้วยตำบล
จาค็อบ

1
คุณจะรู้ได้อย่างไรว่ามันไม่ได้ประมวลผลไดเรกทอรีย่อย?
carlpett

เพราะมันทำให้เกิดข้อผิดพลาดเหล่านี้: sed: ไม่สามารถแก้ไข. / fpd: ไม่ใช่ไฟล์ปกติ sed: ไม่สามารถแก้ไข. /fpd/font: ไม่ใช่ sed ไฟล์ทั่วไป: ไม่สามารถแก้ไข. /fpd/font/makefont: ไม่ใช่ regula
hd

โอ้ ... ฉัน grep สำหรับแอปเปิ้ลและไม่พบพวกเขาทั้งหมดถูกแทนที่ ;) ขอบคุณ . คุณเปิดตาของฉัน !!!
hd

คำตอบ:


422

การค้นหาของคุณควรมีลักษณะเช่นนั้นเพื่อหลีกเลี่ยงการส่งชื่อไดเรกทอรีไปยัง:

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;

19
คุณอาจจะต้องเปลี่ยนsed -i 's/apple/orange/g'ไปsed -i '' 's/apple/orange/g'เพื่อให้งานนี้
paulmelnikow

7
-iรับอาร์กิวเมนต์: ส่วนขยายที่ใช้เพื่อบันทึกไฟล์ชั่วคราว ใน GNU sed ลักษณะเหมือนมีช่องว่างระหว่างไม่มี-iและโต้แย้ง แต่ใน BSD sed มี ... ดังนั้น BSD -i '' 's/foo/bar/'เทียบเท่ากับ -i 's/foo/bar/GNU
paulmelnikow

20
การเพิ่ม-eไม่ได้ทำงานบน Mac OS ตามด้วยคำสั่งข้างต้นผลิตรายการไดเรกทอรีเช่นนี้touch a b c d e a a-e b b-e c c-e d d-e e e-e
paulmelnikow

6
สำหรับ Mac OS คำตอบนี้stackoverflow.com/questions/19242275/...RE error: illegal byte sequence
kakoma

3
สำหรับผู้ใช้งานเปลือกหอยต้องแน่ใจว่าได้อ้างอิงเครื่องหมายวงเล็บเปล่า'{}'เพราะปลาจะขยายเครื่องหมายวงเล็บเปล่าโดยอัตโนมัติหากไม่ยกมา
Kevin Cherepski

84

สำหรับงานที่มีขนาดใหญ่ขึ้นจะเป็นการดีกว่าและเร็วกว่าในการใช้ grep และ xargs ดังนั้นตัวอย่างเช่น;

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'

20
ขอบคุณสำหรับคำตอบนี้มันมีประโยชน์มาก! หากอยู่ในที่เก็บคอมไพล์ก็ยิ่งใช้งานได้เร็วขึ้นgit grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues

4

สิ่งนี้ใช้ได้กับฉัน:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;

คำถามเดิมไม่ จำกัด ไปยังไฟล์ .php * นอกจากนี้ยังมี .ini หนึ่ง
knocte

unquoted *.phpไม่ถูกต้องจริงๆ คุณเพิ่งโชคดีที่มันไม่ได้ขยายในไดเรกทอรีเริ่มต้นเพราะคุณไม่ได้มีไฟล์ที่ตรงกัน
tripleee


1

เนื่องจากมีผู้ใช้ macOS ที่อ่านข้อความนี้ (เหมือนที่ฉันทำ) รหัสต่อไปนี้ใช้งานได้สำหรับฉัน (วันที่ 10.14)

egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @

คำตอบอื่น ๆ ทั้งหมดที่ใช้-iและ-eไม่ทำงานบน macOS

แหล่ง


0

ฉันคิดว่าเราสามารถทำได้ด้วยคำสั่งง่ายๆบรรทัดเดียว

for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ‘s/eth0/eth1/’ $i; done

อ้างถึงหน้านี้


-6

ใน linuxOS:

sed -i 's/textSerch/textReplace/g' namefile

หาก "sed" ไม่ทำงานให้ลอง:

perl -i -pe 's/textSerch/textReplace/g' namefile

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