Mam ponad 10 000 plików o łącznej wielkości ponad 20 GB, które muszę połączyć w jeden plik.
Czy jest szybszy sposób niż
cat input_file* >> out
?
Preferowanym sposobem byłoby polecenie bash, Python jest również akceptowalny, jeśli nie znacznie wolniejszy.
bash
shell-script
files
cat
fsperrle
źródło
źródło
find
nie sortuje plików tak samo jak glob powłoki.out
znajduje się na innym dysku.Odpowiedzi:
Nie, kot jest z pewnością najlepszym sposobem na zrobienie tego. Po co używać Pythona, jeśli w tym celu jest już napisany program w C? Możesz jednak rozważyć użycie
xargs
na wypadek, gdyby długość wiersza poleceń przekroczyłaARG_MAX
i potrzebujesz więcej niż jednegocat
. Przy użyciu narzędzi GNU jest to równoważne z tym, co już masz:źródło
find
są przesyłane strumieniowosort
. Bez tego pliki byłyby wyświetlane w dowolnej kolejności (zdefiniowanej przez system plików, którym może być kolejność tworzenia plików).bash
glob. W przeciwnym razie nie widzę przypadków, w których zachowywałbym sięxargs
lubcat
nie zachowywałbym zgodnie z oczekiwaniami.xargs
zadzwoni tak,cat
jak to konieczne, aby uniknąć błędu E2BIG execve (2).Przydzielenie najpierw miejsca na plik wyjściowy może poprawić ogólną szybkość, ponieważ system nie będzie musiał aktualizować przydziału dla każdego zapisu.
Na przykład, jeśli w systemie Linux:
Kolejną korzyścią jest to, że jeśli nie ma wystarczającej ilości wolnego miejsca, kopia nie zostanie podjęta.
Jeśli jest włączony
btrfs
, możeszcopy --reflink=always
pobrać pierwszy plik (co oznacza brak kopiowania danych i dlatego byłby prawie natychmiastowy), a resztę dołączyć. Jeśli jest 10000 plików, prawdopodobnie nie zrobi to dużej różnicy, chyba że pierwszy plik jest bardzo duży.Istnieje interfejs API do uogólnienia tego, aby ponownie skopiować wszystkie pliki (
BTRFS_IOC_CLONE_RANGE
ioctl
), ale nie mogłem znaleźć żadnego narzędzia udostępniającego ten interfejs API, więc musiałbyś to zrobić w C (python
lub w innych językach, pod warunkiem, że mogą wywoływać dowolneioctl
) .Jeśli pliki źródłowe są rzadkie lub mają duże ciągi znaków NUL, możesz utworzyć rzadki plik wyjściowy (oszczędzając czas i miejsce na dysku) za pomocą (w systemach GNU):
źródło
>
ani>>
, ale,1<>
jak już powiedziałem, aby zapisać do pliku.<>
jest standardowym operatorem przekierowania odczytu i zapisu Bourne / POSIX. Szczegółowe informacje można znaleźć w instrukcji obsługi powłoki lub specyfikacji POSIX . Domyślniefd
jest0
to<>
operator (<>
jest skrótem0<>
, podobnie jak<
skrótem0<
i>
skrótem1>
), więc musisz1
jawnie przekierować standardowe wyjście. Tutaj nie tyle potrzebujemy read + write (O_RDWR
), ale nie chcemyO_TRUNC
(jak w>
), aby cofnęli przydzielenie tego, co właśnie przydzieliliśmy.dd
czytając lub czytając.fallocate
neguje się dodatkowe kosztyfind
, mimo że będzie to szybsze za drugim razem.btrfs
z pewnością otwiera jednak kilka interesujących możliwości.