क्या टेक्स्ट फ़ाइल में कुछ स्ट्रिंग डेटा को प्रस्तुत करने के लिए एक यूनिक्स कमांड है?
कुछ इस तरह:
prepend "to be prepended" text.txt
<<(echo "to be prepended") < text.txt | sponge text.txt
क्या टेक्स्ट फ़ाइल में कुछ स्ट्रिंग डेटा को प्रस्तुत करने के लिए एक यूनिक्स कमांड है?
कुछ इस तरह:
prepend "to be prepended" text.txt
<<(echo "to be prepended") < text.txt | sponge text.txt
जवाबों:
sed -i.old '1s;^;to be prepended;' inFile
-i
यदि कोई एक्सटेंशन दिया जाता है तो स्थान में परिवर्तन लिखता है और बैकअप लेता है। (इस मामले में .old
)1s;^;to be prepended;
दिए गए प्रतिस्थापन स्ट्रिंग द्वारा पहली पंक्ति की शुरुआत का विकल्प देता है, ;
एक कमांड सीमांकक के रूप में उपयोग करते हुए ।\n
प्रेपेंड के बाद डालना चाह सकता है ; उनकी जरूरतों पर निर्भर करता है। नीट समाधान।
inFile
इसमें निर्देशिका को शामिल किया जा सकता है ?
\n
। पहले टिप्पणियों को पढ़ना चाहिए। अरे नहीं।
'1s;^;my-prepended-line\;\n;'
printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt
git config --get-regex $arg | sed -r 's/\t{3}/\\n/g';
और यह गड़बड़ कर देता है क्योंकि यह \t
और परिवर्तित करता है \n
।
echo "to be prepended"$'\n'"$(cat text.txt)"
मुझे आश्चर्य है कि किसी ने भी इसका उल्लेख नहीं किया।
cat <(echo "before") text.txt > newfile.txt
जो स्पष्ट रूप से स्वीकृत उत्तर की तुलना में अधिक स्वाभाविक है (किसी चीज़ को प्रिंट करना और उसे प्रतिस्थापन कमांड में पाइप करना भौगोलिक रूप से काउंटर-सहज ज्ञान युक्त है)।
... और क्या कह रहा है कि sponge
आप एक अस्थायी फ़ाइल की जरूरत नहीं है के साथ ऊपर अपहरण अपहरण :
sudo apt-get install moreutils
<<(echo "to be prepended") < text.txt | sponge text.txt
संपादित करें: ऐसा लगता है कि यह बॉर्न शेल में काम नहीं करता है /bin/sh
यहां एक स्ट्रिंग का उपयोग करना - <<<
आप कर सकते हैं:
<<< "to be prepended" < text.txt | sponge text.txt
<<(echo "to be prepended") < text.txt
और <<< "to be prepended" < text.txt
कंस्ट्रक्शन बैश में काम नहीं करते हैं; उन्हें zsh की आवश्यकता होती है।
यह एक संभावना है:
(echo "to be prepended"; cat text.txt) > newfile.txt
आप शायद एक मध्यवर्ती फ़ाइल के आसपास आसानी से नहीं मिलेंगे।
विकल्प (शेल से बचकर बोझिल हो सकते हैं):
sed -i '0,/^/s//to be prepended/' text.txt
cat <(echo "to be prepended") text.txt > newfile.txt
:। यह सोचने के लिए आओ, मुझे यकीन नहीं है कि मेरा संबंधित है, इसलिए इम एक अलग उत्तर पोस्ट कर रहा है।
यह आउटपुट बनाने के लिए काम करेगा। द - का अर्थ है स्टैंडर्ड इनपुट, जो इको से पाइप के माध्यम से प्रदान किया जाता है।
echo -e "to be prepended \n another line" | cat - text.txt
फ़ाइल को फिर से लिखने के लिए एक अस्थायी फ़ाइल की आवश्यकता होती है क्योंकि इनपुट फ़ाइल में वापस पाइप नहीं किया जा सकता है।
echo "to be prepended" | cat - text.txt > text.txt.tmp
mv text.txt.tmp text.txt
text.txt
अनुरोध के अनुसार पाठ को फ़ाइल में प्रस्तुत नहीं करता है, लेकिन इसे stdout पर प्रदर्शित करता है। अगर उत्पादन ओपी के लिए काम करता है, तो एक अलग फाइल में फनल किया जा सकता है
एडम के जवाब को प्राथमिकता दें
हम स्पंज का उपयोग करना आसान बना सकते हैं । अब हमें एक अस्थायी फ़ाइल बनाने और उसे नाम बदलने की आवश्यकता नहीं है
echo -e "to be prepended \n another line" | cat - text.txt | sponge text.txt
ध्यान दें:
ऐसा करने से अनपेक्षित दुष्प्रभाव हो सकते हैं, विशेष रूप से एक नियमित फ़ाइल के साथ एक सिमलिंक को बदलना, फ़ाइल पर अलग-अलग अनुमतियों के साथ समाप्त होना और फ़ाइल का निर्माण (जन्म) तारीख बदलना।
sed -i
, जैसा कि प्रिंस जॉन वेस्ले के उत्तर में है , कम से कम मूल अनुमतियों को पुनर्स्थापित करने की कोशिश करता है, लेकिन अन्य सीमाएं भी लागू होती हैं।
यहां एक सरल विकल्प है जो एक अस्थायी फ़ाइल का उपयोग करता है (यह संपूर्ण इनपुट फ़ाइल को उस तरह से मेमोरी में पढ़ने से बचाता है जो शिम का समाधान करता है):
{ printf 'to be prepended'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt
0xC0000022L के समाधान के रूप में एक उपखंड ( ) का उपयोग करने की तुलना में एक समूह कमांड ( { ...; ...; }
) का उपयोग करना थोड़ा अधिक कुशल है ।(...; ...)
लाभ हैं:
यह नियंत्रित करना आसान है कि क्या नया पाठ पहली पंक्ति में सीधे होना चाहिए या क्या इसे नई पंक्ति (यों) के रूप में डाला जाना चाहिए (केवल तर्क के \n
लिए संलग्न करें printf
)।
sed
समाधान के विपरीत , यह काम करता है यदि इनपुट फ़ाइल खाली है ( 0
बाइट्स)।
sed
समाधान यदि इरादे एक या अधिक पहले जोड़ें करने के लिए है सरल किया जा सकता पूरे लाइनों मौजूदा सामग्री के लिए (यह मानते हुए इनपुट फ़ाइल गैर खाली है):
sed
के i
समारोह आवेषण पूरे लाइनों:
GNU के साथ sed
:
# Prepends 'to be prepended' *followed by a newline*, i.e. inserts a new line.
# To prepend multiple lines, use '\n' as part of the text.
# -i.old creates a backup of the input file with extension '.old'
sed -i.old '1 i\to be prepended' inFile
एक पोर्टेबल संस्करण जो macOS / BSD के साथ भी काम करता है sed
:
# Prepends 'to be prepended' *followed by a newline*
# To prepend multiple lines, escape the ends of intermediate
# lines with '\'
sed -i.old -e '1 i\
to be prepended' inFile
ध्यान दें कि \
आवश्यक होने के बाद शाब्दिक नई लाइन ।
आदरणीय ed
POSIX उपयोगिता का उपयोग करना :
ध्यान दें:
ed
सर्वप्रथम इनपुट फ़ाइल को संपूर्ण मेमोरी में पहले पढ़ता है ।करने के लिए पहली पंक्ति के लिए सीधे पहले जोड़ें (के साथ के रूप में sed
, यह नहीं होगा काम करता है, तो इनपुट फ़ाइल पूरी तरह से खाली (है 0
बाइट्स)):
ed -s text.txt <<EOF
1 s/^/to be prepended/
w
EOF
-s
दबाया ed
स्थिति संदेश।ed
मल्टी-लाइन के रूप में यहां कैसे प्रदान किया जाता है दस्तावेज़ ( <<EOF\n...\nEOF
), यानी, स्टड के माध्यम से ; डिफ़ॉल्ट रूप से स्ट्रिंग विस्तार है (खोल चर अंतर्वेशित कर रहे हैं) ऐसे दस्तावेजों में प्रदर्शन किया; कि (जैसे, ) को दबाने के लिए उद्घाटन सीमांकक उद्धृत करें <<'EOF'
।1
पहली पंक्ति को वर्तमान रेखा बनाता हैs
मौजूदा रेखा पर एक रेगेक्स-आधारित स्ट्रिंग प्रतिस्थापन करता है, जैसे sed
; आप प्रतिस्थापन पाठ में शाब्दिक नई \
सूचियों को शामिल कर सकते हैं , लेकिन उन्हें -स्कैप किया जाना चाहिए ।w
इनपुट फ़ाइल के परिणाम वापस लिखता है (परीक्षण के लिए, की जगह w
के साथ ,p
ही करने के लिए प्रिंट परिणाम इनपुट फ़ाइल को संशोधित किए बिना,)।करने के लिए एक या अधिक पहले जोड़ें पूरे लाइनों :
साथ ही sed
, i
फ़ंक्शन हमेशा सम्मिलित किए जाने वाले पाठ में एक अनुगामी न्यूलाइन जोड़ता है।
ed -s text.txt <<EOF
0 i
line 1
line 2
.
w
EOF
0 i
बनाता है 0
(फ़ाइल की शुरुआत) वर्तमान लाइन और सम्मिलित करता है मोड ( i
); ध्यान दें कि लाइन नंबर अन्यथा 1
आधारित हैं।.
अपनी पंक्ति में समाप्त किया गया है।संभवतः कुछ भी अंतर्निहित नहीं है, लेकिन आप इस तरह से अपने खुद के बहुत आसानी से लिख सकते हैं:
#!/bin/bash
echo -n "$1" > /tmp/tmpfile.$$
cat "$2" >> /tmp/tmpfile.$$
mv /tmp/tmpfile.$$ "$2"
कम से कम ऐसा कुछ ...
$$
उत्पादन कोड के लिए अपर्याप्त है, हालांकि (Google सिमलिंक अटैक); लेकिन यह निश्चित रूप से एक स्थिर फ़ाइल नाम से बेहतर है।
mktemp
कुछ परिस्थितियों में पहले से तैयार पाठ केवल स्टड से उपलब्ध हो सकता है। तब यह संयोजन काम करेगा।
echo "to be prepended" | cat - text.txt | tee text.txt
यदि आप tee
आउटपुट को छोड़ना चाहते हैं , तो संलग्न करें > /dev/null
।
tee
क्लोबर नहीं करता है? मुझे नहीं लगता - जो इस समाधान को फ़ाइल के स्वास्थ्य के लिए खतरनाक बना देगा। text.txt
cat
lenA=1000000; yes a | head -c $lenA > a.txt; lenB=10000; b=$(yes b | head -c $lenB); echo "$b" | cat - a.txt | tee a.txt > /dev/null
:। यदि lenA
1000000 (1Mb फ़ाइल) है और lenB
10000 (10Kb टेक्स्ट प्रीपेंड) है, तो "a.txt" फ़ाइल को "b" अक्षर के 20Kb के साथ ओवरराइट किया गया है। यह पूरी तरह से टूट गया है। अब, यदि आप प्रीपेन्ड करने के लिए 1Mb a.txt और 1Mb टेक्स्ट का उपयोग करते हैं, तो tee
7Gb + फाइल बनाने वाले लूप में जाता है, मुझे कमांड को रोकना पड़ा। इसलिए, यह स्पष्ट है कि परिणाम बड़े आकारों के लिए अप्रत्याशित है। मुझे इस बात की कोई जानकारी नहीं है कि इसे छोटे आकारों पर काम करना चाहिए या नहीं।
उपाय:
printf '%s\n%s' 'text to prepend' "$(cat file.txt)" > file.txt
ध्यान दें कि यह सभी प्रकार के इनपुट पर सुरक्षित है, क्योंकि कोई विस्तार नहीं है। उदाहरण के लिए, यदि आप पहले से !@#$%^&*()ugly text\n\t\n
काम करना चाहते हैं, तो यह काम करेगा:
printf '%s\n%s' '!@#$%^&*()ugly text\n\t\n' "$(cat file.txt)" > file.txt
अंतिम भाग विचार के लिए छोड़ दिया गया है कमांड प्रतिस्थापन के दौरान फ़ाइल के अंत में व्हाट्सएप हटाने "$(cat file.txt)"
। इसके लिए सभी कार्य-क्षेत्र अपेक्षाकृत जटिल हैं। यदि आप file.txt के अंत में newlines संरक्षित करना चाहते हैं, तो इसे देखें: https://stackoverflow.com/a/22607352/1091436
file.txt
क्या इससे अधिक की सामग्री को तर्क सूची में फिट किया जा सकता है printf
।
उपयोग करने का दूसरा तरीका sed
:
sed -i.old '1 {i to be prepended
}' inFile
यदि लाइन को पूर्व-निर्धारित किया जाना है, तो बहुस्तरीय है:
sed -i.old '1 {i\
to be prepended\
multiline
}' inFile
sed -i '1ito be prepended' inFile
- या यह केवल GNU sed के लिए अनुमति है?
sed
, i
कमांड के बाद एक बैकस्लैश और एक न्यूलाइन होता है, और इनपुट की प्रत्येक पंक्ति को अंतिम सिवाय एक बैकस्लैश के साथ भी समाप्त होता है। GNU आपके द्वारा sed
पूछी गई लाइनों के साथ शॉर्टहैंड की अनुमति देता है, लेकिन यह केवल GNU है sed
जो ऐसा करता है। '
जैसा कि बैश (उबंटू में) में परीक्षण किया गया है, यदि परीक्षण फ़ाइल के माध्यम से शुरू होता है;
echo "Original Line" > test_file.txt
आप निष्पादित कर सकते हैं;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
या, अगर बाश का संस्करण $ () के लिए बहुत पुराना है, तो आप बैकटिक्स का उपयोग कर सकते हैं;
echo "`echo "New Line"; cat test_file.txt`" > test_file.txt
और "test_file.txt" की निम्नलिखित सामग्री प्राप्त करें;
New Line
Original Line
कोई मध्यस्थ फ़ाइल, बस बैश / गूंज।
एक और काफी सीधे आगे समाधान है:
$ echo -e "string\n" $(cat file)
cat
दोहरे उद्धरण चिह्नों में पैरामीटर विस्तार नहीं होना एक डाउनवोट के लिए एक बहुत अच्छा कारण है । यह कोड फ़ाइल की सामग्रियों को शब्दों में विभाजित कर रहा है, और उनमें से प्रत्येक शब्द को एक अलग तर्क के रूप में पारित कर रहा है echo
। आप मूल तर्क सीमाओं को खो देते हैं, आप नई अंक / टैब / आदि खो देते हैं, और मूल पाठ की तरह \t
और तार \n
को टैब और नए के साथ बदल दिया जाता है जैसे कि वे थे।
यदि आपको vi / vim पसंद है, तो यह आपकी शैली अधिक हो सकती है।
printf '0i\n%s\n.\nwq\n' prepend-text | ed file
मैं एक फ़ंक्शन को परिभाषित करने और फिर आयात करने और जहां आवश्यक हो, का उपयोग करने की सलाह देता हूं।
prepend_to_file() {
file=$1
text=$2
if ! [[ -f $file ]] then
touch $file
fi
echo "$text" | cat - $file > $file.new
mv -f $file.new $file
}
फिर इसे इस तरह उपयोग करें:
prepend_to_file test.txt "This is first"
prepend_to_file test.txt "This is second"
आपकी फ़ाइल सामग्री तब होगी:
This is second
This is first
मैं परिवर्तन लॉग अपडेटर को लागू करने के लिए इस दृष्टिकोण का उपयोग करने वाला हूं।