Як додати один файл до іншого в Linux з оболонки?


418

У мене два файли: file1і file2. Як додати вміст, file2щоб file1вміст file1зберігався в процесі?

Відповіді:


610

Використовуйте bash вбудоване перенаправлення (tldp) :

cat file2 >> file1

2
Як зробити, що цільовий файл не належить вам і вам потрібно використовувати sudo?
— Bijay Rungta

1
@BijayRungta: Це здається, що ти відповів на власне запитання. Ви попередньо підключитеся sudoдо catкоманди (і введіть облікові дані, якщо буде запропоновано).
— Девід

вам потрібно ... chmod 777 / тощо / за замовчуванням / docker, щоб дати собі права на запис у цей файл - обов’язково відновіть старі дозволи на файли, колись зроблено
— dayday74

1
@Sigur: Якщо немає способу спрямувати вихід на два файли одночасно, це вимагатиме двох викликів команди.
— Девід

2
@Sigur або поглянути на teeпрограму: cat 1 | tee -a 2 3. Після перемикання --append(або -aна короткий час) ви можете розмістити скільки завгодно файлів .
— Стефан ван ден Аккер

291

cat file2 >> file1

>>Оператор додає висновок в зазначений файл або створює зазначений файл , якщо він не існує.

cat file1 file2 > file3

Це об'єднує два або більше файлів в один. Ви можете мати стільки вихідних файлів, скільки вам потрібно. Наприклад,

cat *.txt >> newfile.txt

Оновлення 20130902
У коментарях eumiro пропонує "не намагайся cat file1 file2 > file1". Причина цього може не призвести до очікуваного результату в тому, що файл, який отримує переадресацію, готується до того, як >буде виконана команда ліворуч від . У цьому випадку спочатку file1обрізається до нульової довжини та відкривається для виведення, потім catкоманда намагається об'єднати файл, який зараз має нульову довжину, та вміст file2у file1. У результаті виходить, що оригінальний вміст програми file1втрачається, а на його місці - копіяfile2 що, ймовірно, не є тим, що очікувалося.

Оновлення 20160919
У коментарях tpartee пропонує посилання на резервну інформацію / джерела. Для авторитетного посилання я направляю доброго читача на сторінку sh man на linuxcommand.org, де зазначено:

Перед виконанням команди його введення та вихід можуть бути перенаправлені за допомогою спеціального позначення, інтерпретованого оболонкою.

Хоча це і говорить читачеві, що вони повинні знати, це легко пропустити, якщо ви не шукаєте цього і розбираєте заяву слово за словом. Найважливіше слово тут «раніше». Перенаправлення завершено (або не вдалося) до виконання команди.

У прикладі випадку cat file1 file2 > file1оболонка спочатку виконує перенаправлення, щоб ручки вводу / виводу знаходилися на місці в середовищі, в якому команда буде виконуватися до її виконання.

Більш приємну версію, в якій пріоритет перенаправлення висвітлюється досить довго, можна знайти на веб-сайті Яна Аллена у формі навчальних програм Linux. Його сторінка Примітки про перенаправлення вводу / виводу має багато що сказати на цю тему, включаючи зауваження, що перенаправлення працює навіть без команди. Передача цього до оболонки:

$ >out

... створює порожній файл з іменем. Оболонка спочатку встановлює перенаправлення вводу / виводу, потім шукає команду, не знаходить жодної і завершує операцію.


17
@asir - не намагайся cat file1 file2 > file1- це не спрацює, як ти, напевно, чекаєш.
— eumiro

5
Насправді це саме те, що йому потрібно. Він каже, "не перезаписуючи поточний файл1". Перші три відповіді повністю проігнорували цю частину питання і запропонували команду, за допомогою >>якої буде модифікований файл file1. T.Rob зробив набагато кращу роботу, пояснюючи свою відповідь, а не просто бігаючи, щоб подати щось, що фактично було невірним. Виходячи з тексту запитання, я вважаю, що cat file1 file2 > file3це відповідна команда, яку шукав @asir.
— dm78

Дякую за добрі слова, Девіде! Те, що @eumiro вказує вище, але не вникає в деталі, - це те, що операція праворуч від цього >виконується спочатку. Таким чином, виконання cat file1 file2 > file1спочатку спершу клобує, file1а потім спробує скопіювати файл, що має нульову довжину, на себе. Це має сенс, коли ви думаєте про порядок, в якому могли б і повинні відбуватися операції, але досить тонкий, щоб він здивував багатьох людей зненацька. Тож якщо нічого іншого, ви та eumiro спонукали до подальшого вдосконалення відповіді. Дякую за це!
— T.Rob

Також не спробуйте cat file1 >> file1, це призведе до того, що файл буде рекурсивно переписаний, я помилково це роблю, і лише за кілька секунд до цього файлу було внесено 50 мільйонів рядків лише за кілька десятків рядків.
— Хендра Узія

Також, щоб зробити його трохи більш стислим, якщо "новий файл" вже існує, >> додається до нього та > замінює його.
— rinogo

43

Примітка : якщо вам потрібно використовувати судо , зробіть це:

sudo bash -c 'cat file2 >> file1'

Звичайний метод простого попередження sudoдо команди не вдасться, оскільки ескалація привілеїв не переходить у вихідне перенаправлення.


6
Ще одна поширена ідіома цеcat file2 | sudo tee -a file1 > /dev/null
— ianw


13

Для довідки, використання ddrescue забезпечує переривчастий спосіб досягнення завдання, якщо, наприклад, у вас є великі файли та потрібно зробити паузу, а потім виконати її в якийсь пізній момент:

ddrescue -o $(wc --bytes file1 | awk '{ print $1 }') file2 file1 logfile

logfileЦе важливий біт. Ви можете перервати процес Ctrl-Cі відновити його, вказавши знову таку ж команду, і ddrescue прочитає logfileта відновиться з того місця, де він припинився. -o AПрапор говорить ddrescue , щоб почати з байта А в вихідному файлі ( file1). Тож wc --bytes file1 | awk '{ print $1 }'просто витягує розмір file1у байтах (ви можете просто вставити у висновок з, lsякщо хочете).

Як вказують ngks у коментарях, мінусом є те, що ddrescue, мабуть, не буде встановлений за замовчуванням, тому вам доведеться встановлювати його вручну. Іншим ускладненням є те, що у ваших сховищах можуть бути дві версії ddrescue: для отримання додаткової інформації див. Це питання askubuntu . Ви хочете, щоб версія GNU ddrescue, а в системах на базі Debian - пакет з назвою gddrescue:

sudo apt install gddrescue

Для інших дистрибутивів перевірте систему управління пакунками на наявність GNU версії ddrescue.


1
На користь нових користувачів: ddrescue є інструментом GNU, але він може не існувати у вашій Linux, Mac чи іншій системі, схожій на unix. Здається, що DDrescue не потрібен POSIX або будь-який інший стандарт.

2

Ще одне рішення:

cat file1 | tee -a file2

tee має перевагу, яку ви можете додати до потрібної кількості файлів, наприклад:

cat file1 | tee -a file2 file3 file3

буде додавати вміст file1до file2, file3і file4.

На чоловіковій сторінці:

-a, --append
       append to the given FILEs, do not overwrite

0

catЦе може бути простим рішенням, але це стає дуже повільним, коли ми стискаємо великі файли find -print- це врятувати вас, хоча вам доведеться використовувати кота один раз.

amey@xps ~/work/python/tmp $ ls -lhtr
total 969M
-rw-r--r-- 1 amey amey 485M May 24 23:54 bigFile2.txt
-rw-r--r-- 1 amey amey 485M May 24 23:55 bigFile1.txt

 amey@xps ~/work/python/tmp $ time cat bigFile1.txt bigFile2.txt >> out.txt

real    0m3.084s
user    0m0.012s
sys     0m2.308s


amey@xps ~/work/python/tmp $ time find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1

real    0m2.516s
user    0m0.028s
sys     0m2.204s

Економія часу, яку ви повідомляєте для команди combo find / cat, полягає в тому, що ви призначаєте лише команду find, яка роздруковує назви файлів. Спробуйте присвоїти цілу команду таким чином: time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1)і вона повинна створювати подібні результати, як лише для вашої кішки.
— JoshMc

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.