Як додати один файл до іншого в 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.