एक फाइल में कई फाइलों की सामग्री को कैसे जोड़ा जाए


174

मैं पाँच फ़ाइलों की सामग्री को एक फ़ाइल में कॉपी करना चाहता हूँ। मैं इसे प्रत्येक फ़ाइल के लिए cp का उपयोग करके करने की कोशिश की। लेकिन वह पिछली फ़ाइल से कॉपी की गई सामग्री को ओवरराइट कर देता है। मैंने भी कोशिश की

paste -d "\n" 1.txt 0.txt

और यह काम नहीं किया।

मैं चाहता हूं कि मेरी स्क्रिप्ट प्रत्येक पाठ फ़ाइल के अंत में नई पंक्ति को जोड़े।

जैसे। फ़ाइलें 1.txt, 2.txt, 3.txt। 0.txt में 1,2,3 की सामग्री डालें

मैं यह कैसे करुं ?



यहां एक और जवाब: stackoverflow.com/questions/2576693/…
निकोस सी।

जवाबों:


308

आपको अपने आउटपुट फ़ाइल में catशेल पुनर्निर्देशन ( >) के साथ (संक्षिप्त के लिए) कमांड की आवश्यकता है

cat 1.txt 2.txt 3.txt > 0.txt

8
होना चाहिए >> सही? और यह भी कि मेरी 0.txt फ़ाइल के सभी पाठ से पहले एक नई पंक्ति क्यों है?
स्टीम

1
क्या आप 0.txt की सामग्री को संरक्षित करना चाहते हैं?
सेह

13
@blasto यह निर्भर करता है। आप एक फ़ाइल को दूसरे पर अपग्रेड करने के >>लिए उपयोग करेंगे , जहां आउटपुट फ़ाइल को उसमें से जो भी निर्देशित हो , को अधिलेखित कर देगा । के रूप में newline के लिए, वहाँ एक नई फ़ाइल में पहले चरित्र के रूप में है ? आप उपयोग करके पता कर सकते हैं , और यह देखकर कि क्या पहला चरित्र ए है । > 1.txtod -c\n
कट्टरपंथी 7

1
@ मूलांक 7 धन्यवाद। दरअसल, मेरी फाइलें foo_1, foo_2, foo_3 जैसी हैं। मैंने आपके कोड को संशोधित करने की कोशिश की - बिल्ली "$ फ़ाइल नाम _" {1,2,3} "। txt", लेकिन यह काम नहीं किया।
वाष्प

1
@blasto आप निश्चित रूप से सही दिशा में जा रहे हैं। बैश निश्चित रूप {...}से फ़ाइल नाम मिलान के लिए फ़ॉर्म स्वीकार करता है , इसलिए शायद उद्धरण आपकी स्क्रिप्ट में कुछ गड़बड़ कर दिया है? मैं हमेशा lsशेल में इस तरह की चीजों के साथ काम करने की कोशिश करता हूं । जब मुझे आदेश मिलता है, तो मैं इसे स्क्रिप्ट के रूप में काटता हूं। आपको -xअपनी स्क्रिप्ट में उपयोगी विकल्प भी मिल सकता है - यह निष्पादन से पहले स्क्रिप्ट में विस्तारित कमांड को प्रतिध्वनित करेगा।
कट्टरपंथी 7

97

एक और विकल्प, आप में से जो अभी भी इस पोस्ट पर ठोकर खाते हैं जैसे मैंने किया है, का उपयोग करना है find -exec:

find . -type f -name '*.txt' -exec cat {} + >> output.file

मेरे मामले में, मुझे एक और अधिक मजबूत विकल्प की आवश्यकता थी जो कि कई उपनिर्देशिकाओं के माध्यम से दिखेगा इसलिए मैंने उपयोग करना चुना find। इसे तोड़कर:

find .

वर्तमान कार्यशील निर्देशिका के भीतर देखें।

-type f

केवल फाइलों में रुचि है, निर्देशिका नहीं आदि।

-name '*.txt'

नाम द्वारा निर्धारित परिणाम को नीचे दिया गया

-exec cat {} +

प्रत्येक परिणाम के लिए बिल्ली आदेश निष्पादित करें। "+" का अर्थ केवल 1 उदाहरण है जो catस्पॉन (thx @gniourf_gniourf) है

 >> output.file

जैसा कि अन्य उत्तरों में बताया गया है, आउटपुट फाइल के अंत में कैट-एड कंटेंट को जोड़ें।


10
इस उत्तर में बहुत सारी खामियां हैं। सबसे पहले, वाइल्डकार्ड *.txtको उद्धृत किया जाना चाहिए (अन्यथा, पूरी findकमांड, जैसा कि लिखा गया है, बेकार है)। एक और दोष घोर भ्रांति से आता है: जिस आदेश को निष्पादित किया जाता है वह नहीं है cat >> 0.txt {} , लेकिन cat {}। आपकी आज्ञा वास्तव में समतुल्य है { find . -type f -name *.txt -exec cat '{}' \; ; } >> 0.txt(मैंने समूह बनाना जोड़ा ताकि आपको एहसास हो कि वास्तव में क्या हो रहा है)। एक और दोष यह है कि findफ़ाइल खोजने जा रहा है 0.txt, और catयह कहकर शिकायत करेगा कि इनपुट फ़ाइल आउटपुट फ़ाइल है
gniourf_gniourf

सुधार के लिए धन्यवाद। मेरा मामला थोड़ा अलग था और मैंने इस मामले में लागू किए गए कुछ गटके के बारे में नहीं सोचा था।
mopo922

आपको >> output.fileअपनी कमांड के अंत में रखा जाना चाहिए , ताकि आप किसी को भी (अपने आप को) यह सोचकर प्रेरित न करें कि हर मिली फ़ाइल के लिए findनिष्पादन होगा cat {} >> output.file
गनीउरफ_ग्निउरफ

वास्तव में अच्छा लग रहा है! एक अंतिम सुझाव: के -exec cat {} +बजाय का उपयोग करें -exec cat {} \;, ताकि केवल एक उदाहरण catकई तर्कों के साथ पैदा हुआ है ( +पोसिक्स द्वारा निर्दिष्ट है )।
गनीउरफ_गनीउरफ

3
अच्छा जवाब और चेतावनी के शब्द - मैंने अपना संशोधित किया: find . -type f -exec cat {} + >> outputfile.txtऔर यह पता नहीं लगा सका कि मेरी आउटपुट फ़ाइल को केवल 50 megs के बावजूद भी gigs में बढ़ना बंद नहीं होगा। ऐसा इसलिए था क्योंकि मैं outputfile.txt को ही अपीयर करता रहा! तो बस उस फ़ाइल को सही ढंग से नाम देना सुनिश्चित करें या इससे बचने के लिए इसे पूरी तरह से दूसरी निर्देशिका में रखें।
इटिसस्टैकओवरफ़्लोप्रो

43

यदि आपके पास एक निश्चित आउटपुट प्रकार है तो कुछ ऐसा करें

cat /path/to/files/*.txt >> finalout.txt

1
ध्यान रखें कि आप मर्ज ऑर्डर बनाए रखने की संभावना खो रहे हैं। यदि आप अपनी फ़ाइलों को नाम दे सकते हैं, तो यह आपको प्रभावित कर सकता है, जैसे। file_1,, file_2file_11, प्राकृतिक क्रम के कारण फाइलें कैसे छांटी जाती हैं।
एमिस्क

16

यदि आपकी सभी फाइलें एकल निर्देशिका में हैं, तो आप बस कर सकते हैं

cat * > 0.txt

फ़ाइलें 1.txt, 2.txt, .. 0.txt में जाएगी


पहले से ही Eswar द्वारा उत्तर दिया गया। ध्यान रखें कि आप मर्ज ऑर्डर बनाए रखने की संभावना खो रहे हैं। यदि आप अपनी फ़ाइलों को नाम दे सकते हैं, तो यह आपको प्रभावित कर सकता है, जैसे। file_1,, file_2file_11, प्राकृतिक क्रम के कारण फाइलें कैसे छांटी जाती हैं।
इमिक्स

10
for i in {1..3}; do cat "$i.txt" >> 0.txt; done

मुझे यह पृष्ठ इसलिए मिला क्योंकि मुझे 952 फाइलों को एक साथ जोड़ने की आवश्यकता थी। यदि आपके पास बहुत सी फाइलें हैं, तो मुझे यह बहुत बेहतर काम लगता है। यह आपको आवश्यक कई संख्याओं के लिए एक लूप देगा और 0.txt के अंत में संलग्न करने के लिए >> का उपयोग करते हुए हर एक को कैट करेगा।


आप बश में ब्रेस विस्तार का उपयोग बिल्ली को लिखने के लिए कर सकते हैं {1,2,3} .txt >> 0.txt
mcheema

9

यदि आपकी सभी फाइलें इसी तरह नामित की जाती हैं, तो आप बस कर सकते हैं:

cat *.log >> output.log

5

एक अन्य विकल्प है sed:

sed r 1.txt 2.txt 3.txt > merge.txt 

या ...

sed h 1.txt 2.txt 3.txt > merge.txt 

या ...

sed -n p 1.txt 2.txt 3.txt > merge.txt # -n is mandatory here

या पुनर्निर्देशन के बिना ...

sed wmerge.txt 1.txt 2.txt 3.txt

ध्यान दें कि अंतिम पंक्ति भी लिखें merge.txt(नहीं wmerge.txt!)। आप w"merge.txt"फ़ाइल नाम, और -nमूक आउटपुट के साथ भ्रम से बचने के लिए उपयोग कर सकते हैं ।

बेशक, आप वाइल्डकार्ड के साथ फ़ाइल सूची को छोटा कर सकते हैं। उदाहरण के लिए, उपरोक्त उदाहरणों में गिने हुए फ़ाइलों के मामले में, आप इस तरह से ब्रेसिज़ के साथ सीमा निर्दिष्ट कर सकते हैं:

sed -n w"merge.txt" {1..3}.txt

4

यदि आपकी फ़ाइलों में हेडर हैं और आप उन्हें आउटपुट फ़ाइल में निकालना चाहते हैं, तो आप उपयोग कर सकते हैं:

for f in `ls *.txt`; do sed '2,$!d' $f >> 0.out; done

3

यदि मूल फ़ाइल में गैर-मुद्रण योग्य वर्ण हैं, तो वे बिल्ली कमांड का उपयोग करते समय खो जाएंगे। Using कैट -v ’का उपयोग करते हुए, गैर-प्रिंटबलों को दृश्यमान वर्ण स्ट्रिंग में परिवर्तित किया जाएगा, लेकिन आउटपुट फ़ाइल में मूल फ़ाइल में वास्तविक गैर-प्रिंटबेल वर्ण अभी भी नहीं होंगे। फ़ाइलों की एक छोटी संख्या के साथ, एक विकल्प को एक संपादक (उदाहरण के लिए विम) में पहली फ़ाइल खोलने के लिए हो सकता है जो गैर-मुद्रण वर्णों को संभालता है। फिर फ़ाइल के निचले भाग में पैंतरेबाज़ी करें और ": r second_file_name" दर्ज करें। यह गैर-मुद्रण वर्ण सहित दूसरी फ़ाइल में खींच लेगा। वही अतिरिक्त फ़ाइलों के लिए किया जा सकता है। जब सभी फ़ाइलों को पढ़ा गया है, तो ": w" दर्ज करें। अंतिम परिणाम यह है कि पहली फ़ाइल में अब वही होगा जो मूल रूप से किया था, साथ ही उन फ़ाइलों की सामग्री भी जो पढ़ी गई थीं।


यह बहुत स्क्रिप्ट योग्य नहीं है।
FKEinternet

1

यदि आप 3 फ़ाइलों की सामग्री को एक फ़ाइल में जोड़ना चाहते हैं, तो निम्नलिखित कमांड एक अच्छा विकल्प होगा:

cat file1 file2 file3 | tee -a file4 > /dev/null

यह सभी फाइलों की सामग्री को फाइल 4 में संयोजित करेगा, कंसोल आउटपुट को फेंक देगा /dev/null

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