बैश में एक ही फाइल में कई टेक्स्ट फाइलों को समेटना


305

एक निर्देशिका में सभी * .Txt फ़ाइल को एक बड़े टेक्स्ट फ़ाइल में संयोजित करने का सबसे तेज़ और सबसे व्यावहारिक तरीका क्या है?

वर्तमान में मैं cygwin के साथ विंडोज़ का उपयोग कर रहा हूं इसलिए मुझे BASH तक पहुंच प्राप्त है।

विंडोज शेल कमांड भी अच्छा होगा लेकिन मुझे संदेह है कि एक है।

जवाबों:


537

यह आउटपुट को all.txt में जोड़ता है

cat *.txt >> all.txt

यह सभी को अधिलेखित करता है

cat *.txt > all.txt

30
आप एक समस्या में भाग सकते हैं, जहां यह all.txt में बिल्‍लगी करता है। मुझे पता है कि मुझे कभी-कभी जीआरपी के साथ यह समस्‍या होती है, यदि बिल्‍कुल ही व्‍यवहार न हो।
rmeador

8
@rmeador हाँ, यह सच है, अगर all.txt पहले से मौजूद है तो आपको यह समस्या होगी। आउटपुट फ़ाइल को एक अलग एक्सटेंशन के साथ प्रदान करके या सभी को अलग फ़ोल्डर में ले जाकर इस समस्या को हल किया जाता है।
रॉबर्ट ग्रीनर

2
बिल्ली * .txt >> tmp; mv tmp all.txt (और सुनिश्चित करें कि all.txt पहले से मौजूद नहीं है)
Renaud

16
मुझे "तर्क सूची बहुत लंबी है" - अनुमान है कि यह 40,000+ फ़ाइलों को संभाल नहीं सकती है।
मैट

32
तर्क सूची से बहुत लंबे समय तक बचें:echo *.txt | xargs cat > all.txt
5hekiki

145

बस याद रखें, अब तक दिए गए सभी समाधानों के लिए, शेल उस क्रम को तय करता है जिसमें फाइलें समवर्ती होती हैं। बैश, IIRC के लिए, यह वर्णानुक्रम है। यदि आदेश महत्वपूर्ण है, तो आपको या तो फाइलों को उचित रूप से नाम देना चाहिए (01file.txt, 02file.txt, आदि ...) या उस क्रम में प्रत्येक फ़ाइल को निर्दिष्ट करें जिसे आप इसे संक्षिप्त करना चाहते हैं।

$ cat file1 file2 file3 file4 file5 file6 > out.txt

33

Windows शेल कमांड typeयह कर सकता है:

type *.txt >outputfile

टाइप typeकमांड भी stderr को फ़ाइल नाम लिखता है, जिसे >पुनर्निर्देशित ऑपरेटर द्वारा कब्जा नहीं किया जाता है (लेकिन कंसोल पर दिखाई देगा)।


2
बस इस बात से अवगत रहें कि यदि आप आउटपुट फाइल को उसी डायरेक्टरी में रखते हैं जो मूल फाइल के रूप में है तो यह दोहराव का कारण बनेगी क्योंकि यह नई आउटपुट फाइल को भी दो बार संयोजित करेगा।
कैथलएमएफ

26

आप copyफ़ाइलों को सुरक्षित करने के लिए Windows शेल का उपयोग कर सकते हैं ।

C:\> copy *.txt outputfile

मदद से:

फ़ाइलों को जोड़ने के लिए, गंतव्य के लिए एक एकल फ़ाइल निर्दिष्ट करें, लेकिन स्रोत के लिए कई फाइलें (वाइल्डकार्ड या फ़ाइल 1 + फ़ाइल 2 + फ़ाइल स्वरूप का उपयोग करके)।


मूल रूप से कोई साइड इफेक्ट के साथ IMHO सबसे साफ समाधान के रूप में यह है कि शुरुआती दुर्भाग्य से यात्रा कर सकते हैं पर्याप्त सराहना नहीं करता है :-(
Grmpfhmbl

ओपी ने बैश के लिए कहा।
बिग रिच

2
क्या आपने प्रश्न पढ़ा है? "विंडोज शेल कमांड भी अच्छा होगा ..."
कार्ल नॉरम

8

सावधान रहें, क्योंकि इनमें से कोई भी विधि बड़ी संख्या में फ़ाइलों के साथ काम नहीं करती है। व्यक्तिगत रूप से, मैंने इस लाइन का उपयोग किया:

for i in $(ls | grep ".txt");do cat $i >> output.txt;done

संपादित करें: जब किसी टिप्पणी में कहा, आप बदल सकते हैं $(ls | grep ".txt")साथ$(ls *.txt)

संपादित करें: @gnourf_gnourf विशेषज्ञता के लिए धन्यवाद, ग्लोब का उपयोग एक निर्देशिका में फ़ाइलों पर पुनरावृति करने का सही तरीका है। नतीजतन, निन्दा वाले भावों $(ls | grep ".txt")को प्रतिस्थापित करना चाहिए *.txt(लेख यहां देखें )।

अच्छा समाधान

for i in *.txt;do cat $i >> output.txt;done

1
क्यों नहीं for i in $(ls *.txt);do cat $i >> output.txt;done?
21

2
अनिवार्य पार्सिंगएलएस लिंक, एक डाउनवोट के साथ (और आप एक से अधिक डाउनवोट के लायक हैं, क्योंकि ls | grepएक गंभीर रूप से खराब एंटीपार्टर्न है)।
ग्नौरफ_ग्निऑरफ

मेरे पास से एक उत्थान मिला क्योंकि यह आउटपुट से पहले फ़ाइल नाम से मनमाने ढंग से परीक्षण / संचालन की अनुमति देता है और यह अभ्यास के लिए त्वरित और आसान और अच्छा है। (मेरे मामले में मैं चाहता था: मैं में * के लिए; गूंज-कर "\ n $ i: \ n"; बिल्ली $ 1; किया)
नाथन चैपल

ls *.txtअगर बहुत सारी फाइलें (तर्क सूची बहुत लंबी त्रुटि) हैं तो क्या वह विफल नहीं होगी ?
राफेल अल्मीडा

6

शेल के साथ सबसे व्यावहारिक तरीका बिल्ली कमांड है। अन्य तरीकों में शामिल हैं,

awk '1' *.txt > all.txt
perl -ne 'print;' *.txt > all.txt

1
यह अधिकांश परिस्थितियों के लिए सही उत्तर होना चाहिए। यदि कोई भी नई फ़ाइल खाली नई पंक्ति के बिना है, तो उपरोक्त सभी catविधि का उपयोग करके समीपवर्ती फ़ाइलों से अंतिम पंक्ति और पहली पंक्ति को हटा दिया जाएगा।
मटूटूट

6

इस दृष्टिकोण के बारे में कैसे?

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

के बाद से ओ पी कहते हैं फ़ाइलें एक ही निर्देशिका में कर रहे हैं, आप जोड़ना पड़ सकता है -maxdepth 1करने के लिए findआदेश।
कोडफॉस्टर

1
बड़ी संख्या में फ़ाइलों के साथ काम करता है, जहां स्वीकृत उत्तर का दृष्टिकोण विफल रहता है
amine

आह मैं चाहता हूँ कि मुझे पता था कि यह प्लस और डबल रीडायरेक्ट क्या संकेत देता है ...
हेलो_अर्थ

यह सही उत्तर होना चाहिए। यह एक शेल स्क्रिप्ट में ठीक से काम करेगा। यहाँ एक समान विधि है अगर आप आउटपुट सॉर्ट करना चाहते हैं:sort -u --output="$OUTPUT_FILE" --files0-from=- < <(find "$DIRECTORY_NAME" -maxdepth 1 -type f -name '*.txt' -print0)
स्टीववे

3
type [source folder]\*.[File extension] > [destination folder]\[file name].[File extension]

उदाहरण के लिए:

type C:\*.txt > C:\1\all.txt

यह C: \ Folder में सभी txt फ़ाइलों को लेगा और इसे all.txt के नाम से C: \ 1 फ़ोल्डर में सेव करेगा।

या

type [source folder]\* > [destination folder]\[file name].[File extension]

उदाहरण के लिए:

type C:\* > C:\1\all.txt

यह फ़ोल्डर में मौजूद सभी फ़ाइलों को ले जाएगा और C: \ 1 \ all.txt में सामग्री डाल देगा


0

आप इस तरह कर सकते हैं: cat [directory_path]/**/*.[h,m] > test.txt

यदि आप {}उन फ़ाइलों के विस्तार को शामिल करने के लिए उपयोग करते हैं जिन्हें आप ढूंढना चाहते हैं, तो अनुक्रमण समस्या है।


0

जब आप किसी समस्या में भाग लेते हैं, जहाँ वह all.txt को all.txt में रखती है, तो आप कोशिश कर सकते हैं कि all.txt विद्यमान है या नहीं, यदि मौजूद नहीं है, तो निकालें

ऐशे ही:

[ -e $"all.txt" ] && rm $"all.txt"


cat *.txt > all.txt >यदि यह मौजूद है तो ऑलराइट को ऑलराइट कर देता है। >>मौजूदा फाइल में डेटा जुड़ता है
ओलेग बोंडारेंको

-4

यह सब बुरा है ...।

ls | grep *.txt | while read file; do cat $file >> ./output.txt; done;

आसान सामान।


6
Eeek! ऐसा मत करो। करोfind . -iname "*.txt" -maxdepth 1 -exec cat {} >> out.txt \;
चिन्मय कांची
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.