क्या फ़ाइल का अंत करने के लिए लाइन को जोड़ने का एक और सरल तरीका `>>` के अलावा है?


21

हाल ही में मैं एक tree_holeफ़ाइल के लिए छोटे वाक्यों की गूंज कर रहा हूं ।

मैं echo 'something' >> tree_holeइस काम को करने के लिए उपयोग कर रहा था ।

लेकिन मुझे हमेशा इस बात की चिंता थी कि अगर मैं >इसके बजाय गलत इनपुट करता हूं, तो मैंने >>अक्सर ऐसा किया।

इसलिए मैंने बैशकॉक में अपना खुद का एक ग्लोबल बैश फंक बनाया:

function th { echo "$1" >> /Users/zen1/zen/pythonstudy/tree_hole; }
export -f th

लेकिन मैं सोच रहा हूं कि क्या फ़ाइल के अंत में लाइनों को जोड़ने का एक और सरल तरीका है। क्योंकि मुझे अन्य अवसरों में इसका उपयोग करने की आवश्यकता हो सकती है।

क्या वहाँ कोई?


9
क्या आप भूल जाते हैं कि आप हर बार प्रवेश करते समय काम का उपयोग कर रहे हैं>? एक बार मेरे पास एक उपनाम था rm="rm -i"और एक अन्य वातावरण rm *में पुष्टि प्रश्नों के इंतजार में लिखा था । आप खतरनाक आदतें सीख रहे हैं!
वाल्टर ए

9
@WalterA एर, उसका "वर्कअराउंड" उसे टाइप करने नहीं देता है> के बजाय >>, वह बस "वें some_sentence" चलाता है, जो कुछ नहीं करता है अगर उपनाम अपरिभाषित है।
रैंडम Random३२

1
@ Ranom832 अपने वें कार्य के लिए सही है। चेतावनी noclobber की तरह "समाधान" के लिए है। जब वह अपने सामान्य खोल में noclobber की तरह कुछ का उपयोग करता है तो वह उपयोग कर सकता है> जब वह अस्थायी जड़ होता है और कुछ जोड़ना चाहता है।
वाल्टर ए

7
@ Random832 & WalterA मैं आमतौर पर इस बारे में कुछ नहीं कहता जब मैं इसे देखता हूं, लेकिन मुझे लगा कि शायद एक बार एक दोस्ताना नोटिस उपयोगी हो सकता है। ज़ेन की उपयोगकर्ता प्रोफ़ाइल में अधिक विवरण नहीं है, इसलिए मुझे यकीन नहीं है कि अगर आप वास्तव में जानते हैं कि उसका "वर्कअराउंड" सही रूप है। शायद आपको उनका "वर्कअराउंड" या ओपी का "वर्कअराउंड" कहना चाहिए । शायद आप ज़ेन को व्यक्तिगत रूप से जानते हैं और इसलिए आप जानते हैं कि उसकी बात सही है, इस मामले में, कृपया शोर को क्षमा करें। कोई बड़ी बात नहीं है, मैं सिर्फ इसका उल्लेख करता हूं क्योंकि मुझे पता है कि मैंने इसकी बहुत सराहना नहीं की होगी यदि आपने मेरे बारे में बात करने के लिए उस फॉर्म का इस्तेमाल किया हो।
सेलदा

1
@ ज़ेन, आपने लिखा है कि आप मिस-इनपुट> के बजाय>> के लिए चिंतित हैं। सेलाडा की योजना आपके वातावरण में जोखिमों को दूर करेगी, और आपके लिए एक अच्छा समाधान है। जब आप अपने पड़ोसी की मदद कर रहे हैं (जिसके पास noclobber नहीं है या ksh का उपयोग कर रहा है) और आपने एक या दो> वर्णों के लिए अपना ध्यान खो दिया है, तो आप गलती से उसकी एक फाइल को ओवरराइट कर सकते हैं। तो हर बार जब आप अपने स्वयं के वातावरण में नोकलोब चेतावनी प्राप्त करते हैं, तो भगवान या सेलाडा को धन्यवाद दें, अपने आप से कहें: ओह, ध्यान से कृपया !, अपना सिर हिलाएं और दो सेकंड प्रतीक्षा करें।
वाल्टर ए

जवाबों:


47

शेल का noclobberविकल्प सेट करें :

bash-3.2$ set -o noclobber
bash-3.2$ echo hello >foo
bash-3.2$ echo hello >foo
bash: foo: cannot overwrite existing file
bash-3.2$ 

3
यह निश्चित उत्तर है। ध्यान दें कि आप अभी भी फ़ाइल को अधिलेखित कर सकते हैं यदि आप इसे मजबूर करते हैं >|zshइस व्यवहार को डिफ़ॉल्ट रूप से सक्षम करता है।
ओरियन

1
@orion आप इसे zsh में कैसे संलग्न / निष्क्रिय करते हैं? मुझे यह स्पष्ट रूप से अक्षम करने की याद नहीं है, लेकिन ओवरराइटिंग मेरे चिड़ियाघर पर ठीक काम करती है।
मुरु

2
यह setopt noclobberऔर है setopt clobber। ऐसा लगता है कि यह बिल्कुल "डिफ़ॉल्ट" नहीं है, यह उन कॉन्फ़िगरेशन फ़ाइलों पर निर्भर करता है जो आपके डिस्ट्रो के साथ शिप की जाती हैं।
ओरियन

@ मरमू को set [+-]Cकिसी भी आधुनिक शेल के लिए काम करना चाहिए
mikeserv

3
@ set +o noclobberबैश में, या set +C
रुस्लान

7

आप चिंतित हैं यदि आपकी फ़ाइल से क्षतिग्रस्त हो जाएगा >आप जोड़ने के लिए अपने फ़ाइल गुण बदल सकते हैं ऑपरेटर केवल:
में ext2 / ext3 / ext4 फाइल सिस्टम: chattr +a file.txt
में XFS फाइल सिस्टम:echo chattr +a | xfs_io file.txt

और यदि आप एक फ़ंक्शन चाहते हैं, तो मैंने पहले से ही अपने लिए एक फ़ंक्शन बनाया (मैंने इसे आउटपुट फाइल में लॉगजींग आउटपुट के लिए उपयोग किया है), आप इसे अपने उद्देश्य के लिए बदल सकते हैं:

# This function redirect logs to file or terminal or both!
#@ USAGE: log option data
# To the file     -f file
# To the terminal -t
function log(){
        read -r data       # Read data from pipe line

        [[ -z ${indata} ]] && return 1    # Return 1 if data is null

        # Log to /var/log/messages
        logger -i -t SOFTWARE ${data}

        # While loop for traveling on the arguments
        while [[ ! -z "$*" ]]; do
                case "$1" in
                        -t)
                                # Writting data to the terminal
                                printf "%s\n" "${data}"
                                ;;
                        -f) 
                                # Writting (appending) data to given log file address
                                fileadd=$2
                                printf "%s %s\n" "[$(date +"%D %T")] ${data}" >> ${fileadd}
                                ;;
                        *)
                                ;;
                esac
                shift           # Shifting arguments
        done
}

2
इस स्क्रिप्ट के साथ कुछ समस्याएं हैं। 1) आपको आम तौर पर $ग्लोबिंग, वर्ड स्प्लिटिंग और संबंधित व्हाट्सएप समस्याओं को रोकने के लिए पैरामीटर विस्तार (सामान के साथ शुरू होता है ) के आसपास दोहरे उद्धरण लगाने चाहिए । ऑनलाइन शेलचेक ऐप इसे और अन्य विभिन्न समस्याओं को बैश स्क्रिप्ट में पकड़ सकता है। एक संबंधित नोट पर "$@"है बहुत अधिक सुरक्षित $*
PM 2Ring

3
2) आपको आम तौर पर इनपुट में किसी भी बैकस्लैश को रोकने के readलिए -rविकल्प के साथ कमांड को निम्नलिखित चरित्र से बचना चाहिए। 3) स्क्रिप्ट वेरिएबल नामों के लिए लोअर केस का उपयोग करने के लिए यह आमतौर पर बैश स्क्रिप्ट में होता है क्योंकि सिस्टम वेरिएबल के लिए ALL UPPER CASE का उपयोग किया जाता है। इसलिए यदि आप अपने स्वयं के चर के लिए ऊपरी मामले का उपयोग करते हैं, तो आप उन लोगों को भ्रमित करेंगे जो आपके कोड को पढ़ते हैं, और आप गलती से सिस्टम चर को क्लोब कर सकते हैं जिसे आप बाद में स्क्रिप्ट में उपयोग करना चाहते हैं। और अगर आप स्क्रिप्ट का स्रोत बनाते हैं, तो यह बाद के आदेशों के लिए चर को बंद कर देगा।
PM 2Ring

3
4) echoफिक्स्ड स्ट्रिंग्स को प्रिंट करने के लिए आसान है, लेकिन यह अनियंत्रित डेटा के साथ अप्रत्याशित चीजें कर सकता है, खासकर जीएनयू सिस्टम पर। इसका उपयोग करना कहीं अधिक सुरक्षित है printf। अधिक जानकारी के लिए, unix.stackexchange.com/questions/65803/… देखें , खासकर स्टीफन चेज़ेलस का जवाब।
PM 2Ring

3
@PM 2Ring, आज मैंने आपसे बहुत सी बातें सीखीं, बहुत बहुत धन्यवाद .. मैं उन्हें जल्द से जल्द ठीक करूंगा।
सिपाहीढ़ सालौर

1
अच्छा काम, Sepahrad!
PM 2Ring

3

teeएपेंड विकल्प के साथ प्रयोग करें :

foo | tee -a some-file
# or
tee -a some-file <<EOF
blah blah
EOF
# or 
tee -a some-file <<<"blah blah"

5
अच्छा विचार, +1, लेकिन मुझे लगता है कि यदि ओपी किसी >चरित्र को भूलने के बारे में चिंतित है तो वे -aविकल्प को भूलने के बारे में चिंतित हो सकते हैं !
सेलदा

@ कैलाडा मैं ऐसा मानता हूं (लेकिन मैं बार-बार कीस्ट्रोक्स के सेट में एक कीस्ट्रोक को याद करने से एक टाइपो का अनुमान लगा सकता हूं, एक विकल्प को भूल जाने की तुलना में ऐसा होने की अधिक संभावना है)।
मुरु

0

कई प्रोग्राम जो ओवरराइटिंग के लिए फाइल खोल सकते हैं, उन्हें वैकल्पिक रूप से एपेंड के लिए खोल सकते हैं, जैसे कि gnu dd।

dd conv=notrunc oflag=append of=file

यह स्टड या बाइट काउंट को दबाने के लिए if= पैरामीटर ऐड में नामित फ़ाइल पढ़ सकता है 2>/dev/null


3
यह उत्तर के रूप में पोस्ट करने से पहले अपने कोड का परीक्षण करने के लिए एक अच्छा विचार ™ है ...
प्रधानमंत्री 2

1
सिफारिश ddकरना एक बुरा विचार है। ddमज़बूती से इसके इनपुट को इसके आउटपुट में नहीं लिखते हैं , तब नहीं जब उनमें से एक नियमित फ़ाइल या ब्लॉक डिवाइस नहीं है
गाइल्स 'एसओ- बुराई को रोकें'

@gilles, आप उस लिंक पर जानकारी को गलत तरीके से प्रस्तुत कर रहे हैं, जब गिनती निर्दिष्ट नहीं है dd उपलब्ध सभी डेटा को कॉपी करेगा, जैसे कि बिल्ली करता है।
जैसन

-1

मैं एक का उपयोग करना चाहते हैं sed(यहां तक ​​कि बैकअप-कॉपी के साथ - बाद extention देखें -i):

sed -i.bak '$ a\something' /Users/zen1/zen/pythonstudy/tree_hole

मैं हैरान क्यों नहीं हूं ... आप एक सेड मनिक, कोस्टा हैं। :) (यह एक तारीफ है, BTW)
PM 2Ring

@ PM2Ring हाँ, मैं बहुत खतरनाक हूँ! : पी
कोस्टास

बेशक जिस तरह से काम करता है वह फ़ाइल की एक प्रतिलिपि बनाने के लिए है, अंत में नया पाठ जोड़ें, फिर मूल फ़ाइल को हटा दें और प्रतिलिपि को मूल नाम पर नाम दें। यदि आपके पास निर्देशिका तक पहुंच नहीं है, तो यह (1) काम नहीं करता है, (2) लिंक तोड़ता है, और (3) संसाधन-महंगा है यदि फ़ाइल बड़ी है। अजीब बात है कि आप "खतरनाक" शब्द लाए हैं!
जी-मैन ने

-1

आप हमेशा फ़ाइल के माध्यम से अन्य तरीकों से तलाश कर सकते हैं ...

seq 10000000 >f
{ wc -l >&2; echo new line\!; } <>f >&0; \
{ wc -l >&2; echo new line\!; } <>f >&0; \
{ wc -l >&2; echo new line\!; } <>f >&0; \
{ wc -l >&2; echo new line\!; } <>f >&0; \
{ wc -l >&2; echo new line\!; } <>f >&0; \
wc -l f; tail f

... यह अजीब लग अनुक्रम प्रिंट:

10000000
10000001
10000002
10000003
10000004
10000005 f
9999996
9999997
9999998
9999999
10000000
new line!
new line!
new line!
new line!
new line!

लेकिन यह थोड़े मूर्खतापूर्ण है।

एक और उपयोगी उदाहरण की तरह लग सकता है:

 apnd() if    shift
        then  wc -l  >&2
              printf "$@"
        fi    <>"$1" >&0

आप इसे कॉल कर सकते हैं जैसे:

 apnd /path/to/file          \
      "${printf_fmt_string}" \
       arbitrary list of strings

और आप एपेंड एक्शन होने fileसे stderrठीक पहले लिखी गई लाइनों की गिनती के साथ हवा करेंगे ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.