Я знаю, cat
что это можно сделать, но его главная цель - объединить, а не просто отобразить контент.
Я также знаю о less
и more
, но я ищу что-то простое ( не пейджер ), которое просто выводит содержимое файла на терминал, и это сделано специально для этого, если есть такая вещь.
cat
объединяет.a+b+c
включает в себя выполнение 2 сложений, а вычислениеa
не требует добавления чего-либо. Точно так же выполнениеcat f
не требует объединения чего-либо (хотя это единственное, что может означать «объединение последовательности из одного файла»).cat
читает файл и записывает другой файл (поток), но это не значит, что он объединяет что-либо. Если вы, возможно, имеете в виду, чтоcat f
на самом деле это делаетcat - f
, это просто неправдаcat
действительно предназначался для объединения (cat file1 file2
объединит оба файла в стандартный вывод). Но побочным эффектом является то, что, когда в качестве аргумента используется только 1 файл, он выводит этот файл на стандартный вывод (куда бы он ни направлялся: либо на ваш терминал, либо на что-то перенаправленное). Таким образом, не было никакой другой команды, созданной только для вывода на стандартный вывод, поскольку онаcat
существовала и позволяла это просто. Поэтому вы хотите использоватьcat
.Ответы:
Самый очевидный из них
cat
. Но также посмотритеhead
иtail
. Есть также другие utillities оболочки для печати файл построчно:sed
,awk
,grep
. Но они должны чередовать содержимое файла или искать внутри файла.Я сделал несколько тестов, чтобы оценить, какой из них наиболее эффективен. Я запускаю все корыта,
strace
чтобы увидеть, какие из них были наименьшими. Мой файл имеет 1275 строк.awk
: 1355 системных вызововcat
: 51 системный вызовgrep
: 1337 системных вызововhead
: 93 системных вызоваtail
: 130 системных вызововsed
: 1378 системных вызововКак видите, даже если
cat
он предназначен для объединения файлов, он самый быстрый и эффективный.sed
,awk
Иgrep
напечатал файл построчно, то почему они имеют более что 1275 системных вызовов.источник
Цель
cat
состоит именно в том, чтобы прочитать файл и вывести его на стандартный вывод.источник
cat --help
говорит "Объединить ФАЙЛ (ы), или стандартный ввод, к стандартному выводу". Я не хочу ничего объединятьreadlink /dev/fd/1
например, - вы должны получить там имя вашего tty, если вы работаете в стандартном приглашении. Поэтому объединение ввода в вывод - это то, что вы просите сделать.Сначала
cat
выполняется запись в стандартный вывод, который не обязательно является терминалом, даже если онcat
был введен как часть команды для интерактивной оболочки. Если вам действительно нужно что-то записать в терминал, даже если стандартный вывод перенаправлен, это не так просто (вам нужно указать, какой терминал, и может даже не быть, если команда выполняется из скрипта), хотя один может (ab) использовать стандартный вывод ошибок, если команда является просто частью конвейера. Но так как вы указали, что наcat
самом деле выполняет свою работу, я полагаю, вы не спрашивали о такой ситуации.Если ваша цель - отправить то, что записано в стандартный вывод, в конвейер, то использование
cat
будет иметь право на награду « Бесполезное использование Cat» , посколькуcat file | pipeline
(гдеpipeline
обозначает любой конвейер) можно сделать более эффективно, чем<file pipeline
. Но опять же, из вашей формулировки я делаю вывод, что это не было вашим намерением.Так что не очень понятно, о чем вы беспокоитесь. Если вы нашли
cat
слишком длинный текст, вы можете определить одно- или двухсимвольный псевдоним (есть еще несколько таких имен, которые остаются неиспользованными в стандартном Unix). Однако, если вы беспокоитесь, чтоcat
тратите бесполезные циклы, вы не должны.Если бы существовала программа,
null
которая не принимает аргументов и просто копирует стандартный ввод в стандартный вывод (нейтральный объект для конвейеров), вы можете делать то, что хотите<file null
. Такой программы не существует, хотя ее было бы легко написать (программа на языке C с помощью однострочнойmain
функции может выполнить эту работу), но вызовcat
без аргументов (или,cat -
если вы хотите быть явным) делает именно это.Если бы существовала
nocat
программа, которая принимает ровно один аргумент имени файла, пытается открыть файл, жалуется на него, если не может, и в противном случае переходит к копированию из файла в стандартный вывод, тогда это будет именно то, что вы просите. Писать его немного сложнее, чемnull
основная работа: открытие файла, тестирование и, возможно, жалоба (если вы дотошны, вы можете также включить тест, в котором есть только один аргумент, и пожаловаться в противном случае). Но опять жеcat
, теперь с одним аргументом, это именно так, поэтому нет необходимости в какой-либоnocat
программе.Если вам удалось написать
nocat
программу, зачем останавливаться на одном аргументе? Заключение кода в циклfor(;*argp!=NULL;++argp)
на самом деле совсем не сложно, добавляет в двоичный файл не более пары машинных инструкций и позволяет избежать необходимости жаловаться на неправильное количество аргументов (что избавляет от множества других инструкций). Вуаля примитивная версияcat
, объединяющая файлы. (Если честно, нужно немного подправить его, чтобы без аргументов он вел себя какnull
.)Конечно, в реальной
cat
программе они добавили несколько наворотов, потому что они всегда так делают. Но суть в том, что аспект «конкатенации»cat
затрат вообще не требует усилий ни для программиста, ни для исполняющей его машины. Тот факт, чтоcat
подводит итогnull
иnocat
объясняет отсутствие таких программ. Избегайте использованияcat
с одним аргументом, если результат попадает в конвейер, но если он используется только для отображения содержимого файла на терминале, даже страница, на которую я ссылался, признает, что это полезное использованиеcat
, так что не стесняйтесь.Вы можете проверить, что
cat
в действительности реализовано простым циклом вокруг гипетическойnocat
функциональности, вызываяcat
несколько имен файлов, среди которых одно недопустимое имя, а не в первой позиции: вместо того, чтобы сразу жаловаться, что этот файл не существует,cat
сначала сбрасывает предыдущий допустимые файлы, а затем жалуется на неверный файл (по крайней мере, так ведет себя моя кошка).источник
При
zsh
попыткеЯ считаю, что это самый короткий способ напечатать файл. Он использует «скрытый»
cat
(или,more
если stdout является терминалом), но команда, используемая для печати, управляетсяREADNULLCMD
переменной, которую вы можете безопасно перезаписать непосредственно по имени команды или даже по какой-либо функции. Например, для печати файлов с нумерацией строк:источник
POSIX определить кошку как:
Поэтому я думаю, что объединение здесь означает чтение файлов по порядку .
источник
Я знаю, что это вопрос прошедшего времени. Технически, поскольку печать содержимого файла
stdout
является формой конкатенации,cat
это семантически целесообразно. Не забывайте, чтоprintf
семантически предназначен для форматирования и печати данных. Bash также предоставляет синтаксис для перенаправления ввода и вывода из файлов. Сочетание этого может привести к этому:источник
cat file.txt
, так как она удалит все завершающие символы новой строки (это$(...)
делает).Используя
bash
встроенные функции и избегая создания подпроцесса:IFS
будет применяться только кread
команде, поэтому не беспокойтесь о ваших глобальныхIFS
изменениях.Цикл необходим для обработки нулевых символов (спасибо Стефану Шазеласу).
Этот способ не подходит для больших файлов, потому что содержимое файла сначала читается в переменную (то есть в память). Кстати, я пытался напечатать текстовый файл 39M таким образом, и использование памяти bash не превышало 5M, поэтому не уверен насчет этого случая.
Он также чертовски медленный и неэффективный процессор: для того же файла 39M это заняло ~ 3 минуты при 100% использовании одного ядра.
Для больших файлов или двоичных файлов лучше использовать
cat '/path/to/file'
или даже,dd if='/path/to/file' bs=1M
если это возможно.источник
pv -q
что в Linux можно использовать,splice()
что для некоторых типов stdin / stdout улучшит производительность.Так же, как демонстрация, вы можете сделать
источник