Команда к содержанию выходного файла к stdout?

Хотя удар не является хорошим решением, после комментария, здесь другое решение

N=10000
while read n;do [[ $n =~ ^[0-9]*$ ]]&&((a[n/N]++));done
for i in ${!a[*]};do echo $((i*N))-$(((i+1)*N-1)) $((a[i]));done

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

29
03.09.2014, 17:48
7 ответов

Самым очевидным является cat. Но, также посмотрите на голову и хвост . Существуют и другие вспомогательные оболочки для печати файла строка за строкой: sed, awk, grep. Но это необходимо для чередования содержимого файла или для поиска внутри файла.

Я сделал несколько тестов, чтобы оценить, какой из них наиболее эффективен. Я прогоняю все корыта strace, чтобы посмотреть, какой из них вызвал меньше всего системных вызовов. В моем файле 1275 строк.

  • awk: 1355 системных вызовов
  • cat: 51 системный вызов
  • grep: 1337 системных вызовов
  • head: 93 системных вызова
  • tail: 130 системных вызовов
  • sed: 1378 системных вызовов

Как видите, даже если cat был разработан для объединения файлов, он является самым быстрым и наиболее эффективным. sed, awk и grep распечатывали файлы построчно, поэтому у них более 1275 системных вызовов.

38
27.01.2020, 19:38

Я знаю, что cat может это сделать, но его главная цель - не просто отображение содержания, а его конкатенация.

Цель cat как раз и заключается в том, чтобы прочитать файл и выдать его в stdout.

22
27.01.2020, 19:38

Во-первых, cat записывает в стандартный вывод, который не обязательно является терминалом, даже если cat был введен как часть команды для интерактивная оболочка. Если вам действительно нужно что-то записать в терминал, даже когда стандартный вывод перенаправлен, это не так просто (вам нужно указать, какой терминал, а его может даже не быть, если команда выполняется из сценария), хотя один может (ab) использовать стандартный вывод ошибок, если команда является просто частью конвейера. Но поскольку вы указали, что cat действительно выполняет эту работу, я полагаю, вы не спрашивали о такой ситуации.

Если ваша цель состояла в том, чтобы отправить то, что написано на стандартный вывод, в конвейер, то использование cat будет иметь право на получение награды Useless Use of Cat Award , поскольку файл кошки | конвейер (где конвейер обозначает любой конвейер) может быть реализован более эффективно как <файловый конвейер . Но опять же, из ваших формулировок я делаю вывод, что это не было вашим намерением.

Так что не совсем понятно, о чем вы беспокоитесь. Если вы обнаружите, что cat слишком длинный для ввода, вы можете определить одно- или двухсимвольный псевдоним (есть еще несколько таких имен, которые не используются в стандартном Unix). Если, однако, вы беспокоитесь что кот тратит бесполезные циклы, вам не следует.

Если бы существовала программа null , которая не принимает аргументов и просто копирует стандартный ввод в стандартный вывод (нейтральный объект для конвейеров), вы могли бы делать все, что хотите, с помощью . Такой программы нет, хотя ее было бы легко написать (программа на C с однострочной функцией main может выполнять эту работу), но вызывая cat без аргументов (или cat - , если вы хотите быть откровенным) делает именно это.

Если бы существовала программа nocat , которая принимает ровно один аргумент имени файла, пытается открыть файл, жалуется, если не может, и в противном случае продолжает копирование из файла в стандартный вывод, тогда это будет именно то, о чем вы просите. Это лишь немного сложнее написать, чем null , основная работа - это открытие файла, тестирование и, возможно, жалоба (если вы дотошны, вы также можете включить тест, который имеет ровно один аргумент, и жаловаться иначе). Но опять же cat , теперь снабженный одним аргументом, делает именно это, поэтому нет необходимости в какой-либо программе nocat .

Если вам удалось написать программу nocat , зачем останавливаться на одном аргументе? Заключение кода в цикл for (; * argp! = NULL; ++ argp) на самом деле совсем не требует усилий, добавляет не более пары машинных инструкций в двоичный файл и позволяет избежать жалоб на неправильное количество аргументов (что позволяет сэкономить гораздо больше инструкций). Вуаля, примитивная версия cat , объединяющая файлы. (Честно говоря, вам нужно немного подправить его, чтобы без аргументов он вел себя как null .)

Конечно, в реальной программе cat они добавили несколько колокольчиков и свистит, потому что так всегда бывает. Но суть в том, что аспект «конкатенации» cat на самом деле вообще не требует никаких усилий ни для программиста, ни для машины, выполняющей его. Тот факт, что cat включает null и nocat , объясняет отсутствие таких программ. Избегайте использования cat с одним аргументом, если результат передается в конвейер, но если он используется только для отображения содержимого файла на терминале, даже страница, на которую я ссылаюсь, допускает, что это полезное использование кот , не сомневайтесь.


Вы можете проверить, что cat действительно реализуется с помощью простого цикла вокруг гипотетической функциональности nocat , вызвав cat с несколькими именами файлов, одно из которых недопустимо. имя, не в первой позиции: вместо того, чтобы сразу жаловаться на то, что этого файла не существует, cat сначала выгружает предыдущие допустимые файлы, а затем жалуется на недопустимый файл (по крайней мере, так ведет себя мой кот ).

11
27.01.2020, 19:38

Я знаю, что это вопрос прошедшего времени. Технически, так как печать содержимого файла на stdout является формой конкатенации, cat является семантически уместным. Не забывайте, что printf семантически предназначен для форматирования и печати данных. Bash также предоставляет синтаксис для перенаправления входных и выходных данных из файлов. Комбинация из них может привести к следующему:

printf '%s' "$(<file.txt)"
5
27.01.2020, 19:38

Под zsh try

<file

I believe it is the short short way to print a file (Я считаю, что это самый короткий способ распечатать файл). Он использует 'скрытый' cat (или more, если stdout - терминал), но команда, используемая для печати, управляется переменной READNULLCMD, которую можно безопасно перезаписать непосредственно по имени команды или даже какой-нибудь функцией. Например, для печати файлов с нумерацией строк:

numcat() { nl -s'> ' -w2 - }
READNULLCMD=numcat
<file
7
27.01.2020, 19:38

POSIX определяют CAT Как:

Имя

CAT - CONCATENATE и PRINT файлы

Synopsis

CAT [-U] [Файл ...]

Описание

Утилита Cat должна прочитать файлы в последовательности и записать их Содержимое к стандартному выходу в той же последовательности.

Так что я думаю ConcateNate здесь означает Читайте файлы в последовательности .

5
27.01.2020, 19:38

В качестве демонстрации можно сделать

cp foo /dev/stdout
4
27.01.2020, 19:38

Теги

Похожие вопросы