Bir dizindeki tüm (metin) dosyalar tek bir dizide nasıl birleştirilir?


89

Hepsi bir metnin parçası olan 14 dosyam var. Onları birleştirmek istiyorum. Bu nasıl yapılır?

Yanıtlar:


168

Bu teknik olarak ne cat("bitiştir") yapması gerekiyor, çoğu insan sadece stdout'a dosya çıktılamak için kullanıyor olsa da. Birden fazla dosya adı verirseniz, hepsini sırayla verir ve ardından bunu yeni bir dosyaya yönlendirebilirsiniz; tüm dosyalar için sadece kullanın *(ya /path/to/directory/*da zaten dizinde değilseniz) ve kabuğunuz tüm dosya adlarına genişletir.

$ cat * > merged-file

15
Alıntıladığınız komutun muhtemelen posterin ne istediğini yapacağına dikkat edin, eğer kabuk *"doğal" düzende genişleyecek şekilde numaralandırılırsa . Eğer "file1.txt ... file9.txt ... file14.txt" 'e sahipseniz, file1? .Txt, file1.txt ve file2.txt arasında sıralanacağından işe yaramaz. Bunları "file01.txt ... file09.txt ... file14.txt" olarak yeniden adlandırmanız gerekir. echo *Emin değilseniz söyleyin .
Warren Young,

2
@Warren: iyi nokta (ya da zsh kullanabilir ve numeric_glob_sortopsiyonunu ayarlayabilirsiniz )
Gilles

2
@ warren-young doğru, faydalı bir uyarı yorumu. Ancak benim gerçek durumumda sıra farketmez (dosyalar sadece bağımlılık içermeyen veri kayıtları ekleyen basit SQL ifadeleri içerirler).
Ivan

2
Dikkat edin, eğer dosya sayısı belirli bir limiti aşarsa, - / bin / cat: Argüman listesi çok uzun olabilir
Nupur

1
@ ARA1307 Yalnızca dosya zaten varsa; Aksi takdirde, kabuk yazmak için dosyayı açmadan önce küre genişletilecektir. Bu durumda İyi bir nokta olsa
Michael Mrozek

25

Dosyalarınız aynı dizinde değilse, birleştirme işleminden önce find komutunu kullanabilirsiniz:

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

Dosyalarınız zaten sipariş edildiğinde ve onları analiz etmek için birleştirmek istediğinizde çok kullanışlıdır.


Daha taşınabilir:

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

Bu, dosya sırasını koruyabilir veya koruyamayabilir.


1
Çok fazla dosyanız varsa, gitmek için yol budur. "Argüman listesi çok uzun" bir hatadan kaçınırsınız.
Мати Тернер

2
-Name * .csv yerine -name "* .csv" ifadesine ihtiyacınız var;
Peteris

Tırnaklara duyulan ihtiyaç, bulma komutunun sürümüne bağlıdır, özel olarak find ve awk'de mac kullanıyorsanız, her iki programın sürümleri biraz eskidir. Şimdiye kadar ubuntu, fötr
şapka

Ben desen eşleştirme geçerli dizinde hiçbir dosya olduğunda çalışmak tırnaksız versiyonunu beklenebilir "*.csv"kabuk sonra hazır bilgi geçerdi beri *hiç find.
RJHunter


9

Komuta

$ cat * > merged-file

aslında birleştirme dosyasına 'birleştirilen dosya' dahil edilmesinin istenmeyen bir yan etkisi vardır, bu bir çalışma dosyası oluşturur. Bunu aşmak için, birleştirilmiş dosyayı farklı bir dizine yazın;

$ cat * > ../merged-file

veya birleştirilmiş dosyayı yoksayacak bir desen eşleşmesi kullanmak;

$ cat *.txt > merged-file

14
cat * > merged-fileiyi çalışıyor. Globs, dosya oluşturulmadan önce işlenir. Eğer merged-filezaten var, cat(en azından benim) o çıktı dosyası olduğunu algılar ve okumak için reddedecektir. Dosya zaten mevcutsa VE daha sonra boru hattında yönlendirmeye sahipseniz, o zaman açıkça yapamazsınız, o zaman ve sonra sadece kaçak dosyayı alırsınız.
Kevin

catDosyanın çıktı olup olmadığını tespit etmenin bir yolu yoktur. Yönlendirme kabukta olur; catsadece stdout'ta yazdırır.
bfontaine

8

Buradan diğerlerinin dediği gibi ... kullanabilirsiniz cat

Diyelim ki:

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

Ve sadece istemek file01için file03ve fileAiçin fileC:

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

Veya, ayraç genişletme kullanarak:

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

Veya meraklısı ayraç genişletme kullanarak:

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

Veya fordöngü kullanabilirsiniz :

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

1
[01-03]İpin genel bir desen olarak çalışmayacağını unutmayın .
Kusalananda

0

patternBir dosyayı belirtebilir, ardından hepsini aşağıdaki şekilde birleştirebilirsiniz:

cat *pattern* >> mergedfile

0

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önlendirmeden ...

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

Son satırın ayrıca merge.txt yazdığını unutmayın (wmerge.txt değil!). Dosya adıyla karışıklığı önlemek için w "merge.txt", sessiz çıktı için -n komutunu kullanabilirsiniz.

Elbette, dosya listesini joker karakterlerle de kısaltabilirsiniz. Örneğin, yukarıdaki örneklerde olduğu gibi numaralandırılmış dosyalar olması durumunda, aralıkları ayraçla şu şekilde belirleyebilirsiniz:

sed -n w"merge.txt" {1..3}.txt
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.