निर्देशिका में सभी (पाठ) फ़ाइलों को एक में कैसे मर्ज किया जाए?


89

मुझे 14 फाइलें मिली हैं जो सभी एक पाठ के हिस्से हैं। मैं उन्हें एक में मिलाना चाहूंगा। उसको कैसे करे?

जवाबों:


168

यह तकनीकी रूप से क्या है cat("कॉन्कैटनेट") माना जाता है, भले ही ज्यादातर लोग इसे स्टेपआउट करने के लिए फ़ाइलों को आउटपुट करने के लिए उपयोग करते हैं। यदि आप इसे कई फ़ाइल नाम देते हैं, तो यह उन सभी को क्रमिक रूप से आउटपुट करेगा, और फिर आप इसे एक नई फ़ाइल में पुनर्निर्देशित कर सकते हैं; सभी फाइलों के मामले में बस उपयोग करें *(या /path/to/directory/*यदि आप पहले से निर्देशिका में नहीं हैं) और आपका शेल इसे सभी फ़ाइल नाम में विस्तारित करेगा

$ cat * > merged-file

15
खबरदार कि आपके उद्धृत कमांड शायद केवल वही करेंगे जो पोस्टर चाहते हैं यदि उन्हें इस तरह से गिना जाता है कि शेल *"प्राकृतिक" क्रम में फैलता है। यदि आपके पास "file1.txt ... file9.txt ... file14.txt" है तो यह काम नहीं करेगा, क्योंकि file1 .txt file1.txt और file2.txt के बीच क्रमबद्ध होगा। आपको उन्हें "file01.txt ... file09.txt ... file14.txt" का नाम बदलना होगा। कहो echo *तो आपको यकीन नहीं होगा।
वॉरेन यंग

2
@Warren: अच्छा बिंदु (या आप zsh का उपयोग कर सकते हैं और इसका numeric_glob_sortविकल्प सेट कर सकते हैं )।
गिल्स

2
@ वॉरेन-यंग एक सही, उपयोगी चेतावनी टिप्पणी। लेकिन मेरे वास्तविक मामले में आदेश को कोई फर्क नहीं पड़ता (क्योंकि फाइलों में डेटा रिकॉर्ड डालने वाले सरल एसक्यूएल बयान होते हैं जिनकी कोई निर्भरता नहीं होती है)।
इवान

2
खबरदार, यदि फाइलों की गिनती एक निश्चित सीमा से अधिक है, तो आप त्रुटियों में भाग सकते हैं जैसे - / बिन / बिल्ली: तर्क सूची बहुत लंबी है
नुपुर

1
@ ARA1307 केवल अगर फ़ाइल पहले से मौजूद है; अन्यथा शेल को विस्तारित किया जाएगा इससे पहले कि शेल उस पर लिखने के लिए फ़ाइल खोल दे। उस स्थिति में अच्छा बिंदु हालांकि
माइकल Mrozek

25

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

find /path/to/directory/ -name *.csv -print0 | xargs -0 -I file cat file > merged.file

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


अधिक सुस्पष्ट रूप से:

find /path/to/directory/ -name *.csv -exec cat {} + > merged.file

यह फ़ाइल क्रम को संरक्षित कर सकता है या नहीं भी कर सकता है।


1
यदि आपके पास बहुत सारी फाइलें हैं तो यह जाने का तरीका है। आप "तर्क सूची बहुत लंबी" त्रुटि से बचते हैं।
Мати Тернер

2
आपको -name * .csv के बजाय "* .csv" की आवश्यकता है - बिना उद्धरण के यह विफल हो जाता है।
पीटरिस

उद्धरणों की आवश्यकता खोज कमांड के संस्करण पर निर्भर करती है, विशेष रूप से खोजने और जागने में यह एक समस्या है जब आप एक मैक पर होते हैं, दोनों कार्यक्रमों के संस्करण थोड़े पुराने हैं। अब तक ubuntu, फेडोरा, डेबियन और CentOS पर यह उद्धरण के बिना सुचारू रूप से काम किया
3nrique0

मुझे उम्मीद होगी कि जब संस्करण "*.csv"शेल से साक्षरता *को पार करेगा, तो पैटर्न से मेल खाने वाली वर्तमान निर्देशिका में कोई फ़ाइल नहीं है, तो काम करने के लिए अछूता संस्करण होगा find
RJHunter


9

आदेश

$ cat * > merged-file

वास्तव में समवर्ती में und मर्ज-फाइल ’सहित अवांछित साइड-इफेक्ट है, जिससे एक रन-वे फ़ाइल बनती है। इसे पूरा करने के लिए, या तो विलय की गई फाइल को एक अलग निर्देशिका में लिखें;

$ cat * > ../merged-file

या एक पैटर्न मैच का उपयोग करें जो मर्ज किए गए फ़ाइल को अनदेखा करेगा;

$ cat *.txt > merged-file

14
cat * > merged-fileठीक काम करता है। फ़ाइल बनाने से पहले ग्लब्स को संसाधित किया जाता है। यदि merged-fileपहले से मौजूद है, cat(मेरा कम से कम) यह पता लगाएगा कि यह आउटपुट फ़ाइल है और इसे पढ़ने से इंकार कर दिया है। यदि फ़ाइल पहले से मौजूद है और आपके पास बाद में पाइप लाइन में रीडायरेक्ट है, तो यह स्पष्ट रूप से ऐसा नहीं कर सकता है, इसलिए और उसके बाद ही आपको रनवे फ़ाइल मिलती है।
केविन

catयह पता लगाने का कोई तरीका नहीं है कि क्या फ़ाइल आउटपुट एक है। पुनर्निर्देशन शेल में होता है; catकेवल स्टडआउट पर प्रिंट करता है।
bfontaine

8

जैसे दूसरे यहाँ से कहते हैं ... आप उपयोग कर सकते हैं cat

आप कहते हैं:

~/file01
~/file02
~/file03
~/file04
~/fileA
~/fileB
~/fileC
~/fileD

और आप केवल चाहते file01करने के लिए file03और fileAकरने के लिए fileC:

cat ~/file01 ~/file02 ~/file03 ~/fileA ~/fileB ~/fileC > merged-file

या, ब्रेस विस्तार का उपयोग:

cat ~/file0{1..3} ~/file{A..C} > merged-file

या, प्रशंसक ब्रेस विस्तार का उपयोग कर:

cat ~/file{0{1..3},{A..C}} > merged-file

या आप forलूप का उपयोग कर सकते हैं :

for i in file0{1..3} file{A..C}; do cat ~/"$i"; done > merged-file

1
ध्यान दें कि स्ट्रिंग [01-03]एक ग्लोबिंग पैटर्न के रूप में काम नहीं करेगा।
Kusalananda

0

आप patternकिसी फ़ाइल को निर्दिष्ट कर सकते हैं, फिर उन सभी को निम्नानुसार मर्ज कर सकते हैं :

cat *pattern* >> mergedfile

0

एक अन्य विकल्प 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

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

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

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