Je sais cat
que cela est possible, mais son objectif principal est de concaténer plutôt que de simplement afficher le contenu.
Je connais aussi less
et more
, mais je cherche quelque chose de simple ( pas un pager ) qui ne fait que sortir le contenu d'un fichier sur le terminal et il est fait spécialement pour cela, s'il y a une telle chose.
cat
concatène.a+b+c
implique d'effectuer 2 ajouts, et l'informatiquea
n'implique rien. De même, l'exécutioncat f
n'implique aucune concaténation (même si c'est la seule chose que "concaténer une séquence d'un fichier" pourrait signifier).cat
lit un fichier et écrit un autre fichier (flux), mais cela ne signifie pas qu'il concatène quoi que ce soit. Si vous voulez peut-être dire quecat f
c'est en train de fairecat - f
, ce n'est tout simplement pas vrai.cat
était vraiment destiné à concaténer (cat file1 file2
concaténera les deux fichiers à stdout). Mais son effet secondaire est que, lorsqu'il n'a qu'un seul fichier comme argument, il génère ce fichier sur stdout (où qu'il aille, soit votre terminal, soit redirigé vers quelque chose). Il n'y avait donc aucune autre commande créée juste pour sortir sur stdout, comme celacat
existait et le permettait simplement. Par conséquent, vous souhaitez utilisercat
.Réponses:
Le plus évident est
cat
. Mais, regardez aussihead
ettail
. Il y a aussi d' autres utillities shell pour imprimer une ligne de fichiers en ligne:sed
,awk
,grep
. Mais ceux-ci consistent à alterner le contenu du fichier ou à rechercher à l'intérieur du fichier.J'ai fait quelques tests pour estimer lequel est le plus efficace. Je cours tous les creux
strace
pour voir lequel a fait le moins d'appels système. Mon fichier contient 1275 lignes.awk
: 1355 appels systèmecat
: 51 appels systèmegrep
: 1337 appels systèmehead
: 93 appels systèmetail
: 130 appels systèmesed
: 1378 appels systèmeComme vous pouvez le voir, même s'il a
cat
été conçu pour concaténer des fichiers, il est le plus rapide et le plus efficace.sed
,awk
etgrep
imprimé le fichier ligne par ligne, c'est pourquoi ils ont plus de 1275 appels système.la source
Le but de
cat
est exactement cela, lire un fichier et sortir sur stdout.la source
cat --help
dit "Concaténer le (s) fichier (s), ou entrée standard, à la sortie standard". Je ne veux rien concaténerreadlink /dev/fd/1
par exemple - vous devriez y trouver le nom de votre tty si vous l'exécutez à une invite standard. Donc, vous devez concaténer l'entrée à la sortie.Tout d'abord,
cat
écrit sur la sortie standard, qui n'est pas nécessairement un terminal, même s'il acat
été tapé dans le cadre d'une commande dans un shell interactif. Si vous avez vraiment besoin de quelque chose à écrire sur le terminal même lorsque la sortie standard est redirigée, ce n'est pas si facile (vous devez spécifier quel terminal, et il pourrait même ne pas y en avoir un si la commande est exécutée à partir d'un script), même si un pourrait (ab) utiliser la sortie d'erreur standard si la commande fait simplement partie d'un pipeline. Mais puisque vous avez indiqué que celacat
fait vraiment l'affaire, je suppose que vous ne posiez pas de question sur une telle situation.Si votre objectif était d'envoyer ce qui est écrit sur la sortie standard dans un pipeline, alors l'utilisation
cat
serait éligible au prix Useless Use of Cat , carcat file | pipeline
(oùpipeline
signifie n'importe quel pipeline) peut être fait plus efficacement<file pipeline
. Mais encore une fois, de votre formulation, je déduis que ce n'était pas votre intention.Il n'est donc pas si clair de quoi vous vous inquiétez. Si vous trouvez
cat
trop de temps pour taper, vous pouvez définir un alias à un ou deux caractères (il y a encore quelques noms de ce type qui restent inutilisés dans Unix standard). Si toutefois vous vous inquiétez decat
passer des cycles inutiles, vous ne devriez pas.S'il y avait un programme
null
qui ne prend aucun argument et copie simplement l'entrée standard vers la sortie standard (l'objet neutre pour les pipelines), vous pouvez faire ce que vous voulez<file null
. Il n'y a pas un tel programme, bien qu'il soit facile d'écrire (un programme C avec juste une fonction d'une lignemain
peut faire le travail), mais appelercat
sans arguments (oucat -
si vous voulez être explicite) fait exactement cela.S'il y avait un
nocat
programme qui prend exactement un argument de nom de fichier, essaie d'ouvrir le fichier, se plaint s'il ne peut pas, et sinon procède à la copie du fichier vers la sortie standard, alors ce serait exactement ce que vous demandez. Il n'est que légèrement plus difficile à écrire quenull
, le travail principal étant d'ouvrir le fichier, de tester et éventuellement de se plaindre (si vous êtes méticuleux, vous voudrez peut-être également inclure un test indiquant qu'il existe un seul argument et vous plaindre du contraire). Mais encore une foiscat
, maintenant fourni avec un seul argument, fait exactement cela, donc il n'y a pas besoin denocat
programme.Une fois que vous avez réussi à écrire le
nocat
programme, pourquoi s'arrêter à un seul argument? Envelopper le code dans une bouclefor(;*argp!=NULL;++argp)
n'est vraiment pas du tout un effort, ajoute tout au plus quelques instructions machine au binaire, et évite d'avoir à se plaindre d'un nombre incorrect d'arguments (ce qui épargne beaucoup plus d'instructions). Voilà une version primitive decat
concaténation de fichiers. (Pour être honnête, vous devez le modifier un peu afin que, sans arguments, il se comporte commenull
.)Bien sûr, dans le vrai
cat
programme, ils ont ajouté quelques cloches et sifflets, car ils le font toujours. Mais l'essentiel est que l'aspect "concaténation" descat
coûts ne demande vraiment aucun effort, ni pour le programmeur ni pour la machine qui l'exécute. Le fait quecat
subsumenull
etnocat
explique la non-existence de tels programmes. Évitez d'utilisercat
avec un seul argument si le résultat va dans un pipeline, mais s'il est utilisé uniquement pour afficher le contenu du fichier sur le terminal, même la page à laquelle je suis lié admet qu'il s'agit d'une utilisation utilecat
, alors n'hésitez pas.Vous pouvez tester ce qui
cat
est vraiment implémenté par une simple boucle autour d'unenocat
fonctionnalité hypothétique , en appelantcat
avec plusieurs noms de fichiers parmi lesquels un nom invalide, pas en première position: plutôt que de vous plaindre tout de suite que ce fichier n'existe pas,cat
vide d'abord le précédent des fichiers valides, puis se plaint du fichier invalide (du moins c'est ainsi que mon chat se comporte).la source
Sous
zsh
essaiJe pense que c'est le moyen le plus court d'imprimer un fichier. Il utilise «caché»
cat
(oumore
si stdout est un terminal), mais la commande utilisée pour l'impression est contrôlée par uneREADNULLCMD
variable que vous pouvez écraser en toute sécurité directement par le nom de la commande ou même par une fonction. Par exemple, pour imprimer des fichiers avec une numérotation de ligne:la source
POSIX définit cat comme:
Je pense donc que concaténer ici signifie lire les fichiers en séquence .
la source
Je sais que c'est une question du passé. Techniquement, puisque l'impression du contenu d'un fichier
stdout
est une forme de concaténation,cat
est sémantiquement appropriée. N'oubliez pas queprintf
c'est sémantiquement destiné à formater et imprimer des données. Bash fournit également une syntaxe pour rediriger l'entrée et la sortie des fichiers. Une combinaison de ces éléments pourrait produire ceci:la source
cat file.txt
, car elle supprimera tous les retours à la ligne (le$(...)
fait).Utilisation des fonctions
bash
intégrées et évitant la création de sous-processus:IFS
sera appliqué uniquement à laread
commande, alors ne vous inquiétez pas de vosIFS
modifications globales .Boucle nécessaire pour gérer les caractères nuls (merci à Stéphane Chazelas).
Cette méthode n'est pas adaptée aux gros fichiers car le contenu du fichier est lu en premier dans la variable (donc la mémoire). BTW J'ai essayé d'imprimer un fichier texte de 39M de cette façon et l'utilisation de la mémoire bash n'a pas dépassé 5M, donc je ne suis pas sûr de ce cas.
Il est également sacrément lent et inefficace sur le processeur: pour le même fichier de 39 millions, cela a pris environ 3 minutes avec une utilisation à 100% d'un seul cœur.
Pour les gros fichiers ou binaires mieux utiliser
cat '/path/to/file'
ou mêmedd if='/path/to/file' bs=1M
si possible.la source
pv -q
qui sous Linux peut utilisersplice()
lequel pour certains types de stdin / stdout améliorera les performances.Tout comme une démonstration, vous pouvez faire
la source