Odpowiedzi:
Jest to technicznie to, co cat
powinien zrobić („konkatenate”), nawet jeśli większość ludzi używa go tylko do wysyłania plików na standardowe wyjście. Jeśli nadasz mu wiele nazw plików, wyprowadzi je wszystkie kolejno, a następnie możesz przekierować je do nowego pliku; w przypadku wszystkich plików po prostu użyj *
(lub /path/to/directory/*
jeśli nie jesteś jeszcze w katalogu), a twoja powłoka rozwinie go do wszystkich nazw plików
$ cat * > merged-file
numeric_glob_sort
opcję).
Jeśli twoje pliki nie znajdują się w tym samym katalogu, możesz użyć polecenia find przed konkatenacją:
find /path/to/directory/ -name *.csv -print0 | xargs -0 -I file cat file > merged.file
Bardzo przydatne, gdy pliki są już zamówione i chcesz je scalić w celu ich analizy.
Bardziej przenośny:
find /path/to/directory/ -name *.csv -exec cat {} + > merged.file
To może, ale nie musi, zachować porządek plików.
"*.csv"
, ponieważ powłoka przekaże literał *
do find
.
Komenda
$ cat * > merged-file
w rzeczywistości ma niepożądany efekt uboczny włączenia „scalonego pliku” do konkatenacji, tworząc plik ucieczki. Aby obejść ten problem, albo zapisz scalony plik w innym katalogu;
$ cat * > ../merged-file
lub użyj dopasowania wzorca, które zignoruje scalony plik;
$ cat *.txt > merged-file
cat * > merged-file
działa w porządku. Globs są przetwarzane przed utworzeniem pliku. Jeśli merged-file
już istnieje, cat
(przynajmniej mój) wykryje, że jest to plik wyjściowy i odmówi jego odczytania. JEŻELI plik już istnieje, a przekierowanie jest później w potoku, to oczywiście nie może tego zrobić, więc wtedy i tylko wtedy otrzymujesz plik niekontrolowany.
cat
nie ma możliwości wykrycia, czy plik jest plikiem wyjściowym. Przekierowanie odbywa się w powłoce; cat
drukuje tylko na standardowym wyjściu.
Tak jak inni mówią tutaj ... Możesz użyć cat
Powiedzmy, że masz:
~/file01
~/file02
~/file03
~/file04
~/fileA
~/fileB
~/fileC
~/fileD
I chcesz tylko file01
do file03
i fileA
do fileC
:
cat ~/file01 ~/file02 ~/file03 ~/fileA ~/fileB ~/fileC > merged-file
Lub używając rozszerzenia nawiasów klamrowych:
cat ~/file0{1..3} ~/file{A..C} > merged-file
Lub za pomocą bardziej rozbudowanego rozszerzenia nawiasów klamrowych:
cat ~/file{0{1..3},{A..C}} > merged-file
Lub możesz użyć for
pętli:
for i in file0{1..3} file{A..C}; do cat ~/"$i"; done > merged-file
[01-03]
nie będzie działał jako wzór globowania.
Możesz określić pattern
plik, a następnie scalić je wszystkie w następujący sposób:
cat *pattern* >> mergedfile
Inną opcją jest sed:
sed r 1.txt 2.txt 3.txt > merge.txt
Lub...
sed h 1.txt 2.txt 3.txt > merge.txt
Lub...
sed -n p 1.txt 2.txt 3.txt > merge.txt # -n is mandatory here
Lub bez przekierowania ...
sed wmerge.txt 1.txt 2.txt 3.txt
Zauważ, że w ostatnim wierszu napisz również merge.txt (nie wmerge.txt!). Możesz użyć w "merge.txt", aby uniknąć pomyłek z nazwą pliku, i -n dla cichego wyjścia.
Oczywiście można także skrócić listę plików za pomocą symboli wieloznacznych. Na przykład w przypadku plików numerowanych, jak w powyższych przykładach, możesz określić zakres z nawiasami klamrowymi w następujący sposób:
sed -n w"merge.txt" {1..3}.txt
*
w „naturalnym” porządku. Jeśli masz „plik1.txt ... plik9.txt ... plik14.txt”, to nie zadziała, ponieważ plik1? .Txt będzie sortować między plikiem1.txt a plikiem2.txt. Musisz zmienić ich nazwę na „plik01.txt ... plik09.txt ... plik14.txt”. Powiedz,echo *
jeśli nie jesteś pewien.