2009-05-25 10 views
53

मुझे किसी फ़ोल्डर (और इसके सबफ़ोल्डर) में सभी फ़ाइलों को खोजने और बदलने की आवश्यकता है। ऐसा करने के लिए लिनक्स खोल कमांड क्या होगा?sed beginner: फ़ोल्डर में सभी घटनाओं को बदलना

उदाहरण के लिए, मैं इसे सभी फाइलों पर चलाने के लिए और पुरानी फ़ाइल को नए, प्रतिस्थापित टेक्स्ट से ओवरराइट करना चाहता हूं।

sed 's/old text/new text/g' 
+0

http://theunixshell.blogspot.com/2012/12/find-and-replace-string-in-all-files.html – Vijay

उत्तर

82

वहाँ केवल sed का उपयोग कर यह करने के लिए कोई रास्ता नहीं है। आप एक साथ कम से कम खोज उपयोगिता का उपयोग करना होगा:

find . -type f -exec sed -i.bak "s/foo/bar/g" {} \; 

यह आदेश प्रत्येक परिवर्तित फ़ाइल के लिए एक .bak फ़ाइल पैदा करेगा।

नोट्स:

  • sed आदेश के लिए -i तर्क, एक जीएनयू विस्तार है, इसलिए आप बीएसडी के sed के साथ इस आदेश चलाकर आप कोई नई फ़ाइल को आउटपुट पुनर्निर्देशित करने के लिए तो नाम बदलने की आवश्यकता होगी रहे हैं यह।
  • find उपयोगिता पुराने यूनिक्स बॉक्स में -exec तर्क लागू नहीं करती है, इसलिए, आपको इसके बजाय | xargs का उपयोग करने की आवश्यकता होगी।
0

मैं सुझाव दे सकता है (आपकी फ़ाइलों का बैकअप लेने के बाद):

find /the/folder -type f -exec sed -ibak 's/old/new/g' {} ';' 
-3

my mass search/replace Perl script को आजमा सकते हैं। जंजीर-उपयोगिता समाधानों पर कुछ फायदे हैं (जैसे शेल मेटाएक्टेक्टर व्याख्या के कई स्तरों से निपटने के लिए नहीं)।

5

पोर्टेबिलिटी के लिए, मैं लिनक्स या बीएसडी के लिए विशिष्ट sed की विशेषताओं पर भरोसा नहीं करता हूं। इसके बजाय मैं यूनिक्स प्रोग्रामिंग पर्यावरण पर कर्नीघान और पाइक की पुस्तक से overwrite स्क्रिप्ट का उपयोग करता हूं।

आदेश तो

find /the/folder -type f -exec overwrite '{}' sed 's/old/new/g' {} ';' 

है और overwrite स्क्रिप्ट (जो मैं जगह पर सभी का उपयोग)

#!/bin/sh 
# overwrite: copy standard input to output after EOF 
# (final version) 

# set -x 

case $# in 
0|1)  echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2 
esac 

file=$1; shift 
new=/tmp/$$.new; old=/tmp/$$.old 
trap 'rm -f $new; exit 1' 1 2 15 # clean up files 

if "[email protected]" >$new    # collect input 
then 
    cp $file $old # save original file 
    trap 'trap "" 1 2 15; cp $old $file  # ignore signals 
      rm -f $new $old; exit 1' 1 2 15 # during restore 
    cp $new $file 
else 
    echo "overwrite: $1 failed, $file unchanged" 1>&2 
    exit 1 
fi 
rm -f $new $old 

है विचार है कि यह एक फ़ाइल को केवल तभी एक कमांड सफल होता है अधिलेखित कर देता है। find में उपयोगी है और यह भी आप क्योंकि खोल फ़ाइल ट्रंकेटस

sed 's/old/new/g' file > file # THIS CODE DOES NOT WORK 

उपयोग करने के लिए इससे पहले कि sed यह पढ़ सकते हैं नहीं चाहेंगे कि जहां।

20

मैं find | xargs cmdfind -exec से अधिक उपयोग करना पसंद करता हूं क्योंकि यह याद रखना आसान है।

यह उदाहरण विश्व स्तर पर अपने वर्तमान निर्देशिका में या नीचे "बार" .txt फ़ाइलें में साथ "foo" की जगह:

find . -type f -name "*.txt" -print0 | xargs -0 sed -i "s/foo/bar/g" 

-print0 और -0 विकल्प बाहर छोड़ दिया जा सकता है अगर आपके फ़ाइलनामों फंकी वर्ण नहीं है जैसे रिक्त स्थान।

+1

आप पर OSX कर रहे हैं, 'कोशिश पाते हैं। -type f -name "* .txt" -print0 | xargs -0 sed -i '' 's/foo/bar/g "' ('-i' तर्क के लिए एक खाली स्ट्रिंग प्रदान करते हुए नोट)। – jkukul

-4

यदि फ़ोल्डर में फ़ाइलों के नाम के कुछ नियमित नाम हैं (जैसे file1, file2 ...) मैंने चक्र के लिए उपयोग किया है।

for i in {1..10000..100}; do sed 'old\new\g' 'file'$i.xml > 'cfile'$i.xml; done 
+0

यह पूछे गए प्रश्न से संबंधित नहीं है। प्रश्न में एक ही फ़ाइल/फ़ोल्डर नाम पैटर्न के बारे में कुछ भी उल्लेख नहीं है। कृपया ऐसे उत्तरों से बचें –

संबंधित मुद्दे