ค้นหาและแทนที่ข้อความภายในหลายไฟล์


84

ฉันต้องการทราบวิธีการค้นหาและแทนที่ข้อความที่ระบุในหลายไฟล์เช่นใน Notepad ++ ในบทช่วยสอนที่เชื่อมโยง

เช่น: http://cybernetnews.com/find-replace-multiple-files/


มันจะไม่มีส่วนต่อประสานกราฟิก แต่ฉันอยากให้คุณตรวจสอบ sed (man sed) เป็นตัวแก้ไขสตรีมที่มีอยู่ตั้งแต่เริ่มต้นของ UNIX
apolinsky

คำตอบ:


136

ที่นี่ฉันใช้ sed เพื่อแทนที่ทุกคำที่เกิดขึ้น "cybernetnews" กับ "cybernet" ในทุก ๆ ไฟล์ที่มีนามสกุล, c, ในไดเรกทอรี, / home / user / directory /

find /home/user/directory -name \*.c -exec sed -i "s/cybernetnews/cybernet/g" {} \;

ชุดรูปแบบทั่วไปเพิ่มเติมที่คุณค้นหาซ้ำจากไดเรกทอรีของการดำเนินการและดำเนินการในไฟล์ปกติเท่านั้นอ่านได้เขียนได้:

find ./ -type f -readable -writable -exec sed -i "s/cybernetnews/cybernet/g" {} \;

2
โหวตให้สิ่งนี้เพราะเป็นวิธีที่มีประสิทธิภาพเช่นนี้
Sabacon

4
โหวตขึ้นเพราะ sed เป็นตัวเลือกที่ดีที่สุด IMO แต่คำตอบจะมีประโยชน์มากขึ้นถ้าคุณอธิบายองค์ประกอบของคำตอบ (โดยส่วนตัวแล้วฉันไม่คุ้นเคยและอยากรู้อยากเห็นเกี่ยวกับ {} \;)
sequoia mcdowell

5
@sequoiamcdowell Woo! ฉันคิดถึงสิ่งนี้! ขอโทษ การจัดฟันหมายถึงโดยทั่วไป "สำหรับการแข่งขันแต่ละครั้ง" และเซมิโคลอนที่หลบหนี (\;) คือการป้องกันการแยกวิเคราะห์สองครั้ง เราไม่ต้องการเปลือกที่เข้ากันได้กับ bourne และ sed พยายามแยกคำสั่งเพียงแค่ sed

@ คริสโตเฟอร์มันทำงานอย่างไรถ้าคำนั้นมีช่องว่างอยู่cyber net news? ฉันจะแปลงนี้เพื่อcyber net?
Khurshid Alam

1
@KhurshidAlam ใช้คลาสอักขระที่มีสวิตช์ -e:sed -i -e "s/cyber\snet\snews/cyber net/g"

27

ตัวแก้ไขสตรีม, sed เป็นเครื่องมือที่มีประสิทธิภาพสำหรับงานประเภทนี้และเป็นตัวเลือกแรกของฉันอย่างไรก็ตามถ้าคุณต้องการทำสิ่งนี้จากโปรแกรมแก้ไขข้อความธรรมดาโดยใช้แอพพลิเคชั่นพื้นฐานของ Ubuntu ฉันขอแนะนำให้คุณดู Jedit , มันมีอยู่ในที่เก็บและสามารถติดตั้งได้โดยพิมพ์ในคอนโซลของคุณ:

sudo apt-get install jedit

เริ่ม jedit คลิกรายการเมนูค้นหาในรายการเมนูคลิกรายการค้นหาในไดเรกทอรีคุณจะเห็นกล่องโต้ตอบด้านล่าง:

Jedit ค้นหาในกล่องโต้ตอบโฟลเดอร์

สิ่งนี้คล้ายกับ Notepad ++ และทำสิ่งเดียวกันฉันเชื่อว่านี่คือสิ่งที่คุณต้องการ


นี้เป็นที่สมบูรณ์แบบสำหรับเมื่อฉันกำลังมองหาสายทั้งหมดของรหัสและลังเลที่จะหลบหนีทุกตัวอักษรเดียว regex sedพิเศษถ้าฉันได้ทำในสิ่งเดียวกันกับ
IQAndreas

คุณสามารถแทนที่บล็อคโค้ด (เช่น html, javascript, ฯลฯ ) ในไม่กี่วินาที
lepe

วิธีนี้ใช้ไม่ได้กับไฟล์จำนวนมากหลังจากผ่านไปสองสามชั่วโมงก็ไม่ได้ทำการแทนที่ แต่ในขณะที่ geany ใช้เวลาสองสามนาทีในการค้นหาสิ่งที่เกิดขึ้นทั้งหมด นี่อาจไม่ใช่การค้นหาที่มีประสิทธิภาพและแทนที่ แต่มันทำให้ห้องอบอุ่นขึ้น
Mark Aroni

19

ตัวเลือก GUI อื่นคือregexxer : สกรีนช็อต regexxer


ทำงานได้อย่างสมบูรณ์แบบ (หากคุณคุ้นเคยกับ Regex แล้ว) ขอบคุณ
เออร์เนสต์

1
แม้กระทั่งหากคุณไม่รู้จัก regex คุณสามารถใช้เครื่องมือนี้เป็นเครื่องมือค้นหาสตริงและแทนที่เครื่องมือได้อย่างง่ายดายและจะทำงานให้คุณโดยไม่ต้องใช้ regex หรืออะไรก็ตาม
Mohd Abdul Mujib

13
perl -pi -e 's/oldtext/newtext/g' *

แทนที่การเกิดขึ้นของ oldtext ใด ๆ โดย newtext ในไฟล์ทั้งหมดในโฟลเดอร์ปัจจุบัน อย่างไรก็ตามคุณจะต้องหลบหลีกอักขระพิเศษทั้งหมดใน oldtext และ newtext โดยใช้เครื่องหมายแบ็กสแลช


9

ตรวจสอบกับGeanyเป็น NPP ที่สมบูรณ์แบบสำหรับการแทนที่ Linux คุณสามารถทำสิ่งนั้นได้อย่างสมบูรณ์และคุณสามารถใช้ regex ได้


ฉันรัก Geany! มันเป็นโปรแกรมแก้ไขรายการโปรดของฉันและมีประสิทธิภาพเพียงพอ
Pisu

1
เท่าที่ฉันสามารถบอกได้ Geany 1.23.1 (มาพร้อมกับ Ubuntu 13.10) อนุญาตให้ค้นหาไฟล์หลาย ๆ ไฟล์โดยใช้ regex แต่ไม่สามารถแทนที่ได้
Drew Noakes

คุณสามารถค้นหาและแทนที่ในไฟล์ Geany หลายไฟล์ถ้าคุณเปิดทั้งหมดแล้วใช้ปุ่ม "ในเซสชั่น" ในกล่องโต้ตอบค้นหา / แทนที่
MV

1
คุณเปิดไฟล์ 5000 รายการในแท็บข้อความได้อย่างไร
Mark Aroni

1
ตกลง regexxer สวยมากสิ่งที่ฉันขอฉันเพิ่งข้ามไปก่อนหน้านี้เนื่องจากชื่อมี regex และฉันก็มักจะหลีกเลี่ยงสิ่งที่จะทำกับ regex แต่ฉันผิดเครื่องมือนี้มีสิ่งที่จำเป็นสำหรับการค้นหาและแทนที่
Mohd Abdul Mujib

3

ฉันเขียนสคริปต์เล็กน้อยเพื่อสิ่งนี้ หากคุณต้องการแค่พื้นฐานและไม่คุ้นเคยกับการใช้งานอื่น ๆ ลองดูที่นี่: http://www.csrdu.org/nauman/2010/12/30/bash-script-to-find-and-replace-in -a ตั้งของไฟล์ /

สคริปต์มีดังต่อไปนี้:

for f in submit_*;
  do sed "s/old_db_name/new_db_name/" < $f > a_$f ;
  mv a_$f $f ;
done

2

find_and_replace_in_files.shคุณสามารถใช้สคริปต์นี้คัดลอกโค้ดและทำให้ไฟล์

ฉันแก้ไขมันเล็กน้อย กรุณาบอกความคิดเห็นของคุณ

# *****************************************************************************************
# find_and_replace_in_files.sh
# This script does a recursive, case sensitive directory search and replace of files
# To make a case insensitive search replace, use the -i switch in the grep call
# uses a startdirectory parameter so that you can run it outside of specified directory - else this script will modify itself!
# *****************************************************************************************

!/bin/bash
# **************** Change Variables Here ************
startdirectory="/your/start/directory"
searchterm="test"
replaceterm="test=ok!"
# **********************************************************

echo "***************************************************"
echo "* Search and Replace in Files Version 01-Aug-2012 *"
echo "***************************************************"

i=0; 

  for file in $(grep -l -R $searchterm $startdirectory)
    do
      cp $file $file.bak
      sed -e "s/$searchterm/$replaceterm/ig" $file > tempfile.tmp
      mv tempfile.tmp $file

    let i++;

      echo "Modified: " $file
    done

echo " *** All Done! *** Modified files:" $i

2

โปรแกรมก็คือSearchMonkey

SearchMonkey เป็นแอปพลิเคชั่น Gtk ที่มีน้ำหนักเบาซึ่งมีจุดมุ่งหมายเพื่อแทนที่การค้นหา / grep ที่ยุ่งยากด้วยส่วนต่อประสานผู้ใช้ที่ลื่นไหลซึ่งให้ตำแหน่งที่แสดงเครื่องหมายและปริมาณของข้อความที่ตรงกันได้อย่างรวดเร็ว เป้าหมายคือการจัดหาเครื่องมือค้นหาที่ใช้งานง่ายและสามารถเข้าถึงได้สำหรับผู้ใช้งานและนักพัฒนาซอฟต์แวร์


2
find . -name "*.txt" |xargs sed -i "s/searched_Text/replacement_Text/g"

ทำงานกับฉันใน fedora


คุณสามารถเพิ่มบรรทัดอธิบายวิธีการปรับปรุงนี้มากกว่าaskubuntu.com/a/84013/158442
muru

@muru มันทำงานได้น้อยลงมากsed! ดังนั้นจึงเร็วกว่ามากในแง่ของเวลา CPU เนื่องจากเวลาในการเข้าถึงไฟล์จะ จำกัด ฉันคิดว่ามันไม่เร็วกว่าเวลานาฬิกา แต่ให้โหลดระบบน้อยลง หมายเหตุxargsจะใส่ชื่อไฟล์จำนวนมากเช่นเดียวกับนักล่าใน commandline ของsedคำสั่งเดียว- เติมขนาดบัฟเฟอร์ที่มีอยู่ตามความยาวของพา ธ
Volker Siegel

อืม ... ถ้านี่ถูกปิดฉันสามารถแทนที่มันด้วยคำอธิบายที่ชัดเจนว่าทำไมมันถึงดีกว่า upvoted
Volker Siegel

@VolkerSiegel ที่สามารถทำได้ด้วยการ+แทน\;ในfindใช่มั้ย?
muru

1
@muru อาจเป็นไปได้ ... "เครื่องมือที่เข้มงวดสำหรับงาน" ของฉัน -instinct ชัดเจนว่าชอบxargsแต่คุณพูดถูก; จากman find: ...-exec command {} + The command line is built in much the same way that xargs...ทำให้ฉันคิดถึงบรรทัดคำสั่งของgit filter-branch... ;)
Volker Siegel

2

ทางออกที่ง่ายมาก: แทนที่*.txtไฟล์ทั้งหมดในโฟลเดอร์string_1ด้วยstring_2:

sed -i 's/string_1/string_2/g' *.txt

คำตอบที่ดี! นอกจากนี้เพียงบางส่วน หากคุณต้องการแทนที่สตริงในไฟล์ใด ๆ ของไดเรกทอรีปัจจุบันซ้ำแล้วลองนี้:sed -i 's/string_1/string_2/g' $(grep -rEl 'string_1' ./)
drugan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.