Как добавить один файл в другой в Linux?

327

У меня есть два файла: file1 и file2. Как добавить содержимое файла file2 в файл1, не перезаписывая текущий файл1. Как это сделать на Ubuntu Linux?

Теги:

9 ответов

437

Ты имеешь в виду вот это?

cat file2 >> file1
  • 10
    Это тоже нужно! Просто интересно, как люди узнали это до интернета. Читайте руководства по Unix и отращивайте бороду?
  • 142
    @ user1443778: На самом деле да. По крайней мере, так мне удалось освоить Linux еще в 90-х годах. Один из приемов, который я обнаружил на старых форумах по Linux, чтобы получить хороший ответ, заключался в следующем: если вы спросите: «Как вы делаете __ в Linux?» затем ожидайте бурную реакцию RTFM и общие оскорбления вашего интеллекта. (Не говоря уже о том, что в каждом дистрибутиве есть свой FM, который говорит разные вещи, если вообще один.) Однако, если вы скажете: «Linux отстой, потому что он не может __! Windows может!» тогда, пока вы все еще будете получать град оскорблений, вы также получите полезную информацию, которую вы хотели в первую очередь :)
Показать ещё 13 комментариев
218

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 оболочка сначала выполняет перенаправление, так что дескрипторы ввода/вывода находятся в месте в среде, в которой команда будет выполнена до ее выполнения.

Более дружественная версия, в которой приоритет перенаправления покрывается по длине, можно найти на веб-сайте Ian Allen в виде учебных курсов Linux. Его страница может многое сказать по этой теме, включая наблюдение, что перенаправление работает даже без команды. Передача этого в оболочку:

$ >out

... создает пустой файл с именем. Сначала оболочка устанавливает перенаправление ввода-вывода, затем ищет команду, не находит и завершает операцию.

  • 16
    @asir - не пытайтесь использовать cat file1 file2 > file1 - это не сработает, как вы, вероятно, ожидаете.
  • 5
    На самом деле это именно то, что ему нужно. Он говорит "без перезаписи текущего файла1". Первые три автора полностью проигнорировали эту часть вопроса и предложили использовать команду >> которая изменит файл file1 . T.Rob проделал гораздо лучшую работу, объясняя свой ответ, чем просто мчался, чтобы представить что-то, что было на самом деле неверно. Основываясь на тексте вопроса, я считаю, что cat file1 file2 > file3 - это подходящая команда, которую искал @asir.
Показать ещё 6 комментариев
33

Примечание: если вам нужно использовать sudo, сделайте следующее:

sudo bash -c 'cat file2 >> file1'

Обычный способ простого добавления команды sudo к команде не удастся, так как эскалация привилегий не переносится в перенаправление вывода.

  • 3
    Еще одна распространенная идиома для этого - cat file2 | sudo tee -a file1 > /dev/null
25

Попробуйте выполнить следующую команду:

cat file2 >> file1
20

команда, которую вы ищете,

cat file2 >> file1
14
cat file1 file2 > file3

file1 и file2 - это два разных файла, и они добавляются для создания третьего файла результата (file3).

11

Просто для справки, использование ddrescue обеспечивает прерывистый способ достижения задачи, если, например, у вас большие файлы и необходимость приостановки, а затем продолжить в какой-то более поздний момент:

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

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

  • 1
    Для новых пользователей: ddrescue - это инструмент GNU, но он может отсутствовать в вашей Linux, Mac или другой unix-подобной системе. По-видимому, ddrescue не требуется POSIX или любым другим стандартом.
  • 0
    // Это отличный ответ. Я удивлен, что никто не дал короткий ответ на языке сценариев или интерактивной программе.
0

Другое решение:

cat file1 | tee -a file2

tee имеет то преимущество, что вы можете добавить столько файлов, сколько хотите, например:

cat file1 | tee -a file2 file3 file3

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

На странице man:

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

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

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
  • 0
    Экономия времени, которую вы сообщаете для своей комбо-команды find / cat, заключается в том, что вы синхронизируете только команду find, которая печатает имена файлов. Попробуйте синхронизировать всю команду, например, так: time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1) и оно должно time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1) результаты, аналогичные вашей команде cat only.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню