जाग के साथ जगह में संशोधन सहेजें


135

मैं सीख awkरहा हूं और मैं जानना चाहूंगा कि क्या फ़ाइल में परिवर्तन लिखने का विकल्प है, sedजहां मैं -iफ़ाइल में संशोधनों को बचाने के लिए विकल्प का उपयोग करूंगा ।

मैं समझता हूं कि मैं परिवर्तनों को लिखने के लिए पुनर्निर्देशन का उपयोग कर सकता हूं। हालाँकि ऐसा करने का कोई विकल्प awkहै?


"रीडायरेक्ट के साथ किसी फ़ाइल को संपादित करना" के अधिक सामान्य उत्तर के लिए serverfault.com/a/547331/313521 भी देखें ।
वाइल्डकार्ड

@Wildcard। वहाँ समाधान बहुत ही नाजुक है। घटनाओं के क्रम पर पूरी तरह से कोई गारंटी नहीं है, और उस समाधान का उपयोग करने से आपका डेटा कम हो सकता है। एक तरफ के रूप में, मैं सीधे उस साइट पर टिप्पणी नहीं कर सकता क्योंकि मुझे ऐसा करने के लिए उस साइट पर 50 प्रतिनिधि की आवश्यकता है। मैं कभी नहीं समझ पाऊंगा कि SO ने यूनिक्स / लिनक्स और सर्वर एडमिन, एट अल में खंडित क्यों किया। IMO, वह एक गलती थी।
विलियम पर्ससेल

@WilliamPursell, "घटनाओं के आदेश पर कोई गारंटी नहीं" - वास्तव में गलत है। एकमात्र नाजुकता जिसका समाधान है यदि सामग्री की लंबाई एक कमांड के लिए अधिकतम लंबाई से बड़ी है। हालांकि, घटनाओं के क्रम की गारंटी है।
वाइल्डकार्ड

@Wildcard क्या ऑर्डर देने की गारंटी देता है?
विलियम पर्ससेल

@WilliamPursell इसे बैश प्रलेखन द्वारा गारंटी दी गई है। अन्य गोले के लिए मुझे नहीं पता। (वैसे, यदि आप अपना खाता लिंक करते हैं, तो आपके पास 100 प्रतिनिधि एसोसिएशन बोनस होगा और टिप्पणी करने में सक्षम होगा।)
वाइल्डकार्ड

जवाबों:


142

नवीनतम GNU Awk में ( 4.1.0 जारी होने के बाद से ), इसमें "inplace" फ़ाइल संपादन का विकल्प है :

[...] नई सुविधा का उपयोग करके बनाया गया "इनहेल्ड" एक्सटेंशन, GNU " sed -i" सुविधा का अनुकरण करने के लिए इस्तेमाल किया जा सकता है । [...]

उदाहरण उपयोग:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3

बैकअप रखने के लिए:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") }
> { print }' file1 file2 file3

1
@sudo_O - "inplace" प्रदर्शन के लिए धन्यवाद। आपके उत्तर का उत्थान किया!
Lind

लगता है कि विकल्प हटा दिया गया हो सकता है? ४.१.३ के साथ, मेरे पास "-इंइंइफाइल-किंलड्यू = इन्क्लॉइल" है
कीथ ह्यूजिट

1
@ मेरे साथ भी यही सवाल था। मैंने अभी इसकी कोशिश की और यह मेरे 4.1.3 पर काम करता है। inplaceवास्तव में एक पुस्तकालय gawkहै जो iiSeymour के उत्तर के अनुसार शामिल है , इसलिए inplaceकुछ ऐसा है जिसे एक के रूप में शामिल किया जा सकता है includefile
cxw

यहां एक महत्वपूर्ण चेतावनी: 'देखी गई' सरणी कमांड में शामिल सभी फाइलों से डुप्लिकेट लाइनों को भरेगी। इसलिए यदि प्रत्येक फ़ाइल में उदाहरण के लिए एक सामान्य हेडर है, जिसे पहले वाले के बाद हर फाइल में हटा दिया जाएगा। यदि आप इसके बजाय प्रत्येक फ़ाइल का स्वतंत्र रूप से इलाज करना चाहते हैं, तो आपको * .txt में f के लिए कुछ करने की आवश्यकता होगी; gawk -i inplace '! देखा [$ 0] ++' "$ f"; किया
निक K9

136

जब तक आपके पास GNU 4.1.0 या बाद का समय नहीं है ...

आपके पास ऐसा विकल्प नहीं होगा जैसा कि sed के -iविकल्प के बजाय ऐसा करते हैं:

$ awk '{print $0}' file > tmp && mv tmp file

नोट: -iयह जादू नहीं है, यह एक अस्थायी फ़ाइल भी बना रहा है जो sedआपके लिए इसे संभालती है।


ग्नू के रूप में 4.1.0 जाग ...

GNU awkइस कार्यक्षमता को संस्करण 4.1.0 (10/05/2013 को जारी) में जोड़ा गया । यह -iजारी किए गए नोटों में वर्णित विकल्प के रूप में देने के लिए उतना सीधा नहीं है :

नए -i विकल्प (xgawk से) का उपयोग awk लाइब्रेरी फ़ाइलों को लोड करने के लिए किया जाता है। यह -f से अलग है कि पहले गैर-विकल्प तर्क को एक स्क्रिप्ट के रूप में माना जाता है।

आपको inplace.awkएक्सटेंशन को ठीक से इनवॉइस करने के लिए बंडल किए गए फ़ाइल शामिल करने की आवश्यकता है जैसे:

$ cat file
123 abc
456 def
789 hij

$ gawk -i inplace '{print $1}' file

$ cat file
123
456
789

चर INPLACE_SUFFIXका उपयोग बैकअप फ़ाइल के लिए एक्सटेंशन को निर्दिष्ट करने के लिए किया जा सकता है:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print $1}' file

$ cat file
123
456
789

$ cat file.bak
123 abc
456 def
789 hij

मुझे खुशी इस सुविधा जोड़ दिया गया है हूँ, लेकिन मेरे लिए, कार्यान्वयन बहुत awkish के रूप में सत्ता भाषा की संक्षिप्तता से आता है और नहीं है -i inplaceबहुत लंबा 8 अक्षर है imo

यहां आधिकारिक शब्द के लिए मैनुअल का लिंक दिया गया है।


क्या आपका 'पहला' उदाहरण अधिक पसंद नहीं होना चाहिए awk '{ gsub(/foo/, "bar" ) } ; { print $0 }' file > tmp.txt && mv -v tmp.txt file:?
टोनी बर्गांस्की

मेरे आश्चर्य के लिए, अप्रैल 2019 तक, अभी भी gawk 4.0.2 पर है। किसी को भी आपको ऐसा न बताने दें और ऐसा संस्करण उपलब्ध होगा।
जॉन लुनजर

से कम awk '{print $0}' file | sponge fileका उपयोग कर लिट्टी । spongemoreutils
brablc

15

@sudo_O के पास सही उत्तर है

यह काम नहीं कर सकता:

someprocess < file > file

शैल कुछ नियंत्रण ( पुनर्निर्देश ) पर नियंत्रण सौंपने से पहले पुनर्निर्देश करता है । पुनर्निर्देशन शून्य आकार (करने के लिए फ़ाइल काटना होगा पुन: निर्देशित उत्पादन )। इसलिए, जब तक कुछ प्रॉपर लॉन्च नहीं हो जाता और फाइल से पढ़ना चाहता है, तब तक पढ़ने के लिए कोई डेटा नहीं है।>


14

बस थोड़ा सा हैक जो काम करता है

echo "$(awk '{awk code}' file)" > file

एक जादू की तरह काम करता है! लेकिन क्या यह संभव है कि awk कमांड को वेरिएबल में सेव करें और इसे अपनी निफ्टी ट्रिक में इस्तेमाल करें?
आश्रममुन

13

एक विकल्प का उपयोग करना है sponge:

awk '{print $0}' your_file | sponge your_file

जहाँ आप '{print $0}'अपनी awk स्क्रिप्ट और your_fileउस फ़ाइल के नाम से प्रतिस्थापित करते हैं जिसे आप जगह में संपादित करना चाहते हैं।

sponge फ़ाइल में सहेजने से पहले पूरी तरह से इनपुट को अवशोषित करता है।


स्पंज कितना मानक / पोर्टेबल है?
थॉमस

2
spongeका हिस्सा है moreutils। इसलिए यह अधिकांश प्रणालियों में डिफ़ॉल्ट रूप से मौजूद नहीं होगा। लेकिन ऐसा लगता है कि कम से कम spongeखुद काफी पोर्टेबल है और लगभग हर जगह चलाया जा सकता है।
मारसॉफ्ट

1
-Based की तुलना में इस समाधान का नकारात्मक पहलू यह teeहै कि spongeनीचे लिखने से पहले रैम को सब कुछ पढ़ा जाएगा, इसलिए यह बड़ी फ़ाइलों पर फ्रीज हो जाएगा।
मारसॉफ्ट


3

मामले में आप एक अस्थायी फ़ाइल बनाने के बिना केवल एक अजीब समाधान चाहते हैं और संस्करण के साथ प्रयोग करने योग्य है! = (Gawk 4.1.0):

awk '{a[b++]=$0} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file

4
लेकिन क्या यह पूरी फ़ाइल को मेमोरी में बफर करता है? 20GB फ़ाइल पर विचार करें।
अमित नायडू

0

टी का उपयोग करना

 awk '{awk code}' file | tee file

teeआदेश ले जगह और बाद निष्पादित awkआदेश की वजह से समाप्त हो गया है |


5
यह गलत है। दो आदेशों को समानांतर में निष्पादित किया जाता है, और डेटा को तुरंत पाइप के पार प्रवाहित किया जाता है। बफर (मेरी मशीन पर 8192 बाइट्स) से बड़ी कोई भी फ़ाइल काट दी जाएगी
ट्रिपफ्लैग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.