2012-05-24 12 views
10

Próbuję, używając basha, scalić zawartość listy plików (więcej niż 1K) w dużym pliku.shell - cat - scalanie zawartości plików w jeden duży plik

Próbowałem następujące polecenia cat:

cat * >> bigfile.txt 

jednak co ta komenda robi to wszystko połączyć, obejmował również rzeczy już połączone.

np. plik1.txt

content1 

file2.txt

content2 

file3.txt

content3 

file4.txt

content4 

bigfile.txt

content1 
content2 
content3 
content2 
content3 
content4 
content2 

ale chciałbym tylko

content1 
content2 
content3 
content4 

wewnątrz pliku txt

Innym sposobem byłoby cat file1.txt file2.txt ... i tak dalej ... ale nie mogę zrobić dla więcej niż pliki 1k!

Dziękujemy za wsparcie!

Odpowiedz

18

Problem polega na tym, że umieszczasz bigfile w tym samym katalogu, co czyni go częścią *. Więc coś

cat dir/* > bigfile 

powinien po prostu pracować, jak chcesz go, ze swoimi fileN.txt plików znajdujących się w dir/

+1

... lub 'cat *>/tmp/bigfile; mv/tmp/bigfile. ". – tripleee

+0

Myślę, że fabioln celowo dodaje "bigfile.txt" w danych wejściowych; chce dodać do pliku z różnych 'file * .txt', ale eliminuje duplikaty w tym samym czasie. – chepner

+0

Dziękuję wam. Tak, to był problem! Umieściłem plik bigfile w tym samym katalogu ... więc użyłem polecenia, które mi dałeś (cat dir/*> bigfile)! Jeszcze jedno pytanie: dlaczego umieściłeś> zamiast >> czy to jest to samo? Dziękuję Ci! – fabioln79

-3

Spróbuj:

cat `ls -1 *` >> bigfile.txt 

nie mam maszynę unix przydatny w momencie najpierw przetestuj to dla ciebie.

+2

-1 To niczego nie rozwiązuje i wprowadza kilka nowych problemów. Nie używaj 'ls', gdy symbol wieloznaczny już rozwija się do żądanych plików! Nie używaj niecytowanych nazw plików (danych wyjściowych z odsyłaczy), ponieważ ulegają one uszkodzeniu, jeśli nazwy plików zawierają spacje. – tripleee

+0

Myślałem o pętli, kiedy to napisałem, ale nie wyszło mi to z głowy. I tak lubię odpowiedź Bartona. – JerseyMike

4

Po ponownym przeczytaniu pytania wydaje się, że chcesz dodać dane do bigfile.txt, ale bez dodawania duplikatów. Będziesz musiał przejść przez wszystko sort -u odfiltrować duplikaty:

sort -u * -o bigfile.txt 

Opcja -o sortowania pozwala bezpiecznie zawierać treści bigfile.txt na wejściu do sortowania zanim plik zostanie nadpisany wyjściu.

EDIT: Zakładając bigfile.txt jest sortowana, można spróbować proces dwuetapowy:

sort -u file*.txt | sort -um - bigfile.txt -o bigfile.txt 

Najpierw posortować pliki wejściowe, usuwanie duplikatów.Mamy rura że wyjście do innego procesu sort -u, ten przy użyciu opcji -m oraz który mówi sort połączenie dwóch wcześniej posortowane pliki. Dwa pliki, które połączymy, to - (standardowe wejście, strumień pochodzący z pierwszego sort) i sam bigfile.txt. Ponownie używamy opcji -o, aby umożliwić nam zapisanie wyniku z powrotem do bigfile.txt po przeczytaniu go jako danych wejściowych.

+0

Poprawiłem odpowiedź, aby umożliwić połączenie nowych danych w plik bigfile.txt w taki sposób, aby pozostały posortowane bez wprowadzonych duplikatów. Myślę, że jest to najlepsze, co możesz zrobić bez przełączania się do bardziej ustrukturyzowanego formatu (takiego jak baza danych). – chepner

4

można zachować plik wyjściowy w tym samym katalogu, po prostu trzeba być nieco bardziej wyrafinowane niż *:

shopt -s extglob 
cat !(bigfile.txt) > bigfile.txt 
+0

Dziękuję. Mam pytanie związane z tym poleceniem: katalog zawierający plik ma rozmiar 557 GB, jednak utworzony plik big size ma rozmiar 495. Nie wiem, jak to wyjaśnić. Robię coś nie tak? Dziękuję Ci! – fabioln79

+0

@ fabioln79 Przy podanej ilości informacji, podejrzewam, że może to być spowodowane faktycznie używanym miejscem a rozmiarem bloku (Odczyt na tym ostatnim) – user66001

2

Innym sposobem byłoby kot plik1.txt file2.txt .. i tak dalej ... ale nie mogę tego zrobić dla plików większych niż 1k!

To, co jest dla xargs:

find . -maxdepth 1 -type f -name "file*.txt" -print0 | xargs -0 cat > bigfile.txt 
+0

czy xargs wykonuje komendę dla * każdego * argumentu? Jeśli tak, to czy zamiast ">" należy użyć ">>"? Myślę, że kiedy to zrobi, bigfile.txt będzie zawierał tylko zawartość ostatniego pliku przekazanego do niego. – JerseyMike

+1

xargs uruchamia polecenie raz dla wszystkich argumentów, nie musisz używać '' >> ''. –

+0

Dziękuję za wyjaśnienia. Strona man nie była dla mnie zbyt jasna. – JerseyMike

1

To stara sprawa, ale wciąż dam innego podejścia z xargs

  1. listy plików, które chcesz aby Concat

    ls | grep [wzór]> filelist

  2. Przegląd pliki są w odpowiedniej kolejności z vi lub cat. Jeśli używasz przyrostek (1, 2, 3, ..., n), to nie powinno być problemem

  3. Tworzenie ostatecznej plik

    kot FileList | xargs cat >> [końcowy plik]

  4. Usuń listę plików

    rm -f filelist

nadzieję, że to pomoże ktoś