क्या प्रत्येक को बदलने से पहले मुझे पुछने के लिए सीक बनाने का कोई तरीका है? अंदर की जगह का उपयोग करते समय 'ग' के समान कुछ।
क्या sed यह सब करता है?
क्या प्रत्येक को बदलने से पहले मुझे पुछने के लिए सीक बनाने का कोई तरीका है? अंदर की जगह का उपयोग करते समय 'ग' के समान कुछ।
क्या sed यह सब करता है?
जवाबों:
इसके साथ ऐसा करना sed
संभव नहीं होगा क्योंकि यह एक गैर-संवादात्मक स्ट्रीम संपादक है। sed
एक स्क्रिप्ट में लपेटकर बहुत अधिक सोच की आवश्यकता होगी। यह सिर्फ इसके साथ करना आसान है vim
:
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' file.in
चूंकि यह नीचे टिप्पणियों में उल्लेख किया गया था, यहां यह बताया गया है कि वर्तमान फ़ाइलों में एक विशेष फ़ाइल नाम ग्लोबिंग पैटर्न से मेल खाने वाली कई फ़ाइलों पर इसका उपयोग कैसे किया जाएगा:
for fname in file*.txt; do
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
या, यदि आप पहले यह सुनिश्चित करना चाहते हैं कि फ़ाइल में वास्तव में एक पंक्ति है जो दिए गए पैटर्न से मेल खाती है, तो प्रतिस्थापन करने से पहले,
for fname in file*.txt; do
grep -q 'PATTERN' "$fname" &&
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
उपरोक्त दो शेल लूप find
कमांड में संशोधित किए गए हैं जो समान चीजें करते हैं लेकिन सभी फाइलों के लिए एक विशेष नाम के साथ कहीं या कुछ top-dir
निर्देशिका में,
find top-dir -type f -name 'file*.txt' \
-exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
find top-dir -type f -name 'file*.txt' \
-exec grep -q 'PATTERN' {} \; \
-exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
या, मूल शेल छोरों का उपयोग करके और find
उन में फ़ीड पथनाम रखने के लिए:
find top-dir -type f -name 'file*.txt' -exec sh -c '
for pathname do
vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
done' sh {} +
find top-dir -type f -name 'file*.txt' -exec sh -c '
for pathname do
grep -q "PATTERN" "$pathname" &&
vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
done' sh {} +
आप करते हैं, किसी भी मामले में, नहीं की तरह कुछ करना चाहता हूँ for filename in $( grep -rl ... )
के बाद से
grep
लूप के पहले पुनरावृत्ति को शुरू करने से पहले खत्म होने वाले रनिंग, जो कि अयोग्य हो , औरgrep
पर शब्दों में विभाजित किया जाएगा, और ये शब्द फिल्नाम ग्लोबबिंग से गुजरेंगे (यह उन नामों को अयोग्य बनाता है जिनमें रिक्त स्थान और विशेष वर्ण हैं)।सम्बंधित:
sed
यह है कि यह कई फाइलों, जैसे, sed -i 's/old/new/g' /path/to/*.txt
या कुछ समान पर काम कर सकता है ।
for i in $(grep -rl "old"); do vim -c "%s/old/new/gc" -c "wq" "$i"; done
आप ऐसा करके प्राप्त कर सकते हैं:
:%s/OLD_TEXT/NEW_TEXT/gc
विशेष रूप से, c
तीसरे परिसीमन के बाद जोड़ना ।
ध्यान दें कि 'c' विकल्प केवल Vim में काम करता है; आप sed
कमांड लाइन पर इसका उपयोग नहीं कर पाएंगे ।
sed
।
vim
, इसलिए यह उत्तर लागू है; हालाँकि, स्पष्ट रूप से विम और
आप sed
फ़ाइल पर अपना काम कर सकते हैं और फिर परिणाम को एक अस्थायी फ़ाइल में सहेज सकते हैं, जिसे आप तब उपयोग कर मूल फ़ाइल में पैच कर सकते sdiff
हैं (देखें http://www.gnu.org/software/diffutils/manual/diffutils.html # चालान-एसडीएफ ):
sed -r 's/something/something_else/g' my_file > tmp_file
sdiff -o my_file -s -d my_file tmp_file
searchandreplace () {
if [ -z $2 ] ; then
realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
else
realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
exp=$(realpath * | xargs grep -ins --directories=skip --color=never "$1" | cut -d':' -f1,2 | awk -F':' '{print $2 $1}' | sed -E "s|^[0-9]+|sed -i \'&s/|; s|//|/"$1"/"$2"/g\' /|")
IFS=$'\n'
for d in $exp
do
read -p "Exec $(echo -e -n "\033[1;31m$d\033[0m")? " -e REP
if [ "$REP" = y ]; then
echo `bash -c $d`;
fi
done
fi
}
यदि आप searchandreplace "AAA"
इसे एकल तर्क के साथ खिलाते हैं - - यह केवल वर्तमान निर्देशिका में उस स्ट्रिंग को खोजता है, लेकिन यदि आप इसे दोहरे तर्कों के साथ फ़ीड करते हैं - searchandreplace AAA BBB
- तो उपरोक्त के अलावा यह आपको दूसरी "लाइन" के साथ पहले को बदलने के लिए भी कहता है। लाइन "हर लाइन के लिए।