Birden çok dosyanın içeriği tek bir dosyaya nasıl eklenir


174

Beş dosyanın içeriğini olduğu gibi bir dosyaya kopyalamak istiyorum. Her dosya için cp kullanarak yapmayı denedim. Ancak bu, önceki dosyadan kopyalanan içeriklerin üzerine yazar. Ben de denedim

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

ve işe yaramadı.

Komut dosyamın her metin dosyasının sonuna satırsonu eklemesini istiyorum.

Örneğin. Dosyalar 1.txt, 2.txt, 3.txt. 1,2,3 içeriğini 0,txt'ye koy

Nasıl yaparım ?



Yanıtlar:


308

Çıktı dosyanıza catkabuk yeniden yönlendirmesi ( >) içeren (bitiştirmek için kısa) komutuna ihtiyacınız vardır

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

8
olmalı >> değil mi? ve ayrıca neden 0.txt dosyamdaki tüm metinden önce yeni satır var?
Buhar

1
0.txt içeriğini korumak istediniz mi?
sehe

13
@blasto bağlıdır. Bir dosyayı diğerine eklemek>> için kullanılır , burada çıktı dosyasının üzerine yönlendirilmiş olanlarla üzerine yazılır . Yeni satıra gelince, dosyadaki ilk karakter olarak yeni satır var mı? Kullanarak ve ilk karakterin a olup olmadığını öğrenebilirsiniz . > 1.txtod -c\n
radical7

1
@ radical7 Teşekkürler. Aslında, dosyalarım foo_1, foo_2, foo_3 gibidir. Kodunuzu - cat "$ filename _" {1,2,3} ". Txt" olarak değiştirmeye çalıştım, ancak işe yaramadı.
Steam

1
@blasto Kesinlikle doğru yöne gidiyorsunuz. Bash kesinlikle {...}dosya adı eşleşmesi için formu kabul eder , bu yüzden tırnak işaretleri senaryoda biraz dağınık olabilir mi? Her zaman böyle bir şeyle lskabukta kullanarak çalışmayı denerim . Komutu doğru bulduğumda, sadece bir komut dosyasına olduğu gibi kes-n-yapıştır. -xSeçeneği komut dosyalarınızda da yararlı bulabilirsiniz - yürütmeden önce komut dosyasındaki genişletilmiş komutları yankılandıracaktır.
radical7

97

Benim gibi hala bu yazıya rastlayanlar için başka bir seçenek kullanmaktır find -exec:

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

Benim durumumda, kullanmayı seçtiğim için birden fazla alt dizine bakacak daha sağlam bir seçeneğe ihtiyacım vardı find. Yıkmak:

find .

Geçerli çalışma dizinine bakın.

-type f

Sadece dosyalarla ilgilenir, dizinlerle değil vs.

-name '*.txt'

İsme göre ayarlanan sonucu yavaşlatın

-exec cat {} +

Her sonuç için cat komutunu yürütün. "+", yalnızca 1 örneğinin catoluştuğu anlamına gelir (thx @gniourf_gniourf)

 >> output.file

Diğer yanıtlarda açıklandığı gibi, cat-ed içeriğini bir çıktı dosyasının sonuna ekleyin.


10
Bu cevapta birçok kusur var. İlk olarak, joker karakter *.txttırnak içine alınmalıdır (aksi takdirde, findyazıldığı gibi tüm komut işe yaramaz). Yürütüldüğünde, komut: Başka kusur brüt yanılgıya geliyor değil cat >> 0.txt {} ama cat {}. Komutunuz aslında eşdeğerdir { find . -type f -name *.txt -exec cat '{}' \; ; } >> 0.txt(gerçekten neler olduğunu anlamanız için gruplama ekledim). Başka bir kusur olduğunu finddosyayı bulmak için gidiyor 0.txtve catsöyleyerek şikayet girdi dosyası çıktı dosyası .
gniourf_gniourf

Düzeltmeler için teşekkürler. Benim durumum biraz farklıydı ve bu davadan bazılarının bu davaya uygulandığını düşünmemiştim.
mopo922

Sen koymalıyız >> output.filesen düşünce içine kimseyi (siz dahil) kusturmayn böylece, komutadan sonunda findçalıştırır cat {} >> output.fileher Bulunan dosyayı için.
gniourf_gniourf

Gerçekten iyi görünmeye başlıyor! Son bir öneri: -exec cat {} +bunun yerine kullanın -exec cat {} \;, böylece yalnızca bir örneği catbirden fazla argümanla ortaya çıkar ( +POSIX tarafından belirtilir ).
gniourf_gniourf

3
İyi cevap ve uyarı kelimesi - Benimkini şu şekilde değiştirdim: find . -type f -exec cat {} + >> outputfile.txtve dizin sadece 50 megs olsa bile çıktı dosyamın neden konserlere dönüşmeyi durduramayacağını anlayamadım. Çünkü kendi kendine outputfile.txt eklemeye devam ettim! Bu nedenle, bundan kaçınmak için bu dosyayı doğru bir şekilde adlandırdığınızdan veya başka bir dizine tamamen yerleştirdiğinizden emin olun.
Thisisstackoverflow

43

Belirli bir çıktı türünüz varsa böyle bir şey yapın

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

1
Yine de birleştirme düzenini koruma olasılığını kaybettiğinizi unutmayın. Bu, dosya adınız varsa örneğin sizi etkileyebilir. file_1,, file_2file_11, Doğal düzen nedeniyle dosyaların nasıl sıralanacağı.
emix

16

Tüm dosyalarınız tek bir dizindeyse,

cat * > 0.txt

1.txt, 2.txt, .. dosyaları 0.txt'ye gider


Zaten Eswar tarafından cevaplandı. Yine de birleştirme düzenini koruma olasılığını kaybettiğinizi unutmayın. Bu, dosya adınız varsa örneğin sizi etkileyebilir. file_1,, file_2file_11, Doğal düzen nedeniyle dosyaların nasıl sıralanacağı.
emix

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

Bu sayfayı buldum çünkü 952 dosyayı bir araya getirmem gerekiyordu. Çok fazla dosyanız varsa, bunun daha iyi çalıştığını buldum. Bu, ihtiyacınız olan birçok sayı için bir döngü yapar ve 0.txt'nin sonuna eklemek için her birini >> kullanarak kullanın.


Yazma kedi {1,2,3} .txt >> 0.txt için bash ayracı genişleme kullanabilirsiniz
mcheema

9

Tüm dosyalarınız benzer şekilde adlandırılmışsa şunları yapabilirsiniz:

cat *.log >> output.log

5

Başka bir seçenek sed:

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

Veya...

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

Veya...

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

Veya yönlendirme olmadan ...

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

Son satırın da yazdığını unutmayın merge.txt(değil wmerge.txt!). Sen kullanabilirsiniz w"merge.txt"dosya adıyla karışıklığı önlemek için ve -nsessiz çıkış için.

Tabii ki, dosya listesini joker karakterlerle de kısaltabilirsiniz. Örneğin, yukarıdaki örneklerde olduğu gibi numaralandırılmış dosyalar durumunda, aralığı şu şekilde parantezle belirtebilirsiniz:

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

4

dosyalarınız başlık içeriyorsa ve bunları çıktı dosyasında kaldırmak istiyorsanız, şunları kullanabilirsiniz:

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

3

Orijinal dosya yazdırılamayan karakterler içeriyorsa, cat komutu kullanılırken kaybolacaktır. 'Cat -v' kullanıldığında yazdırılamaz karakterler görünür karakter dizelerine dönüştürülür, ancak çıktı dosyası yine de orijinal dosyada yazdırılamayan gerçek karakterleri içermez. Az sayıda dosyayla, ilk dosyayı yazdırılmayan karakterleri işleyen bir düzenleyicide (örneğin vim) açmak da bir alternatif olabilir. Ardından dosyanın altına manevra yapın ve ": r second_file_name" girin. Bu, yazdırılmayan karakterler de dahil olmak üzere ikinci dosyayı çeker. Aynı şey ek dosyalar için de yapılabilir. Tüm dosyalar okunduğunda ": w" girin. Sonuçta, ilk dosya orijinal olarak yaptığı şeyi ve okunan dosyaların içeriğini içerecektir.


Bu çok yazılabilir değil.
FKEinternet

1

3 dosyanın içeriğini bir dosyaya eklemek istiyorsanız, aşağıdaki komut iyi bir seçim olacaktır:

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

Konsol çıktısını atarak tüm dosyaların içeriğini dosya4'te birleştirir /dev/null.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.