web-dev-qa-db-fra.com

Concaténez plusieurs fichiers mais incluez le nom de fichier comme en-tête de section

Je voudrais concaténer un certain nombre de fichiers texte en un seul fichier volumineux dans le terminal. Je sais que je peux le faire en utilisant la commande cat. Cependant, je voudrais que le nom de fichier de chaque fichier précède le "vidage de données" pour ce fichier. Quelqu'un sait-il comment faire ça?

ce que j'ai actuellement:

file1.txt = bluemoongoodbeer

file2.txt = awesomepossum

file3.txt = hownowbrowncow

cat file1.txt file2.txt file3.txt

sortie désirée:

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow
289
Nick

Je cherchais la même chose et j'ai trouvé ceci suggérer:

tail -n +1 file1.txt file2.txt file3.txt

Sortie:

==> file1.txt <==
<contents of file1.txt>

==> file2.txt <==
<contents of file2.txt>

==> file3.txt <==
<contents of file3.txt>

S'il n'y a qu'un seul fichier, l'en-tête ne sera pas imprimé. Si vous utilisez GNU utils, vous pouvez utiliser -v pour toujours imprimer un en-tête.

425
DS.

J'ai utilisé grep pour quelque chose de similaire:

grep "" *.txt

Il ne vous donne pas un en-tête, mais préfixe chaque ligne avec le nom du fichier.

163
Theo

Cela devrait faire l'affaire aussi:

find . -type f -print -exec cat {} \;

Veux dire:

find    = linux `find` command finds filenames, see `man find` for more info
.       = in current directory
-type f = only files, not directories
-print  = show found file
-exec   = additionally execute another linux command
cat     = linux `cat` command, see `man cat`, displays file contents
{}      = placeholder for the currently found filename
\;      = tell `find` command that it ends now here

Vous pouvez également combiner des recherches avec des opérateurs booléens tels que -and ou -or. find -ls c'est bien aussi.

87
Maxim_united

Cela devrait faire l'affaire:

for filename in file1.txt file2.txt file3.txt; do
    echo "$filename"
    cat "$filename"
done > output.txt

ou faire ceci pour tous les fichiers texte récursivement:

find . -type f -name '*.txt' -print | while read filename; do
    echo "$filename"
    cat "$filename"
done > output.txt
21
Chris Eberle
find . -type f -print0 | xargs -0 -I % sh -c 'echo %; cat %'

Cela imprimera le nom de fichier complet (y compris le chemin), puis le contenu du fichier. Il est également très flexible car vous pouvez utiliser -name "expr" pour la commande find et exécuter autant de commandes que vous le souhaitez sur les fichiers.

15
kevinf

J'ai eu une série de fichiers qui se sont terminés dans stats.txt que je voulais concaténer avec les noms de fichiers.

J'ai fait ce qui suit et quand il y a plus d'un fichier, la commande "plus" inclut le nom du fichier comme en-tête.

more *stats.txt > stats.txt

ou pour un cas général

more FILES_TO_CONCAT > OUTPUT_FILE
15
Steinfadt

Voici comment je gère normalement le formatage comme ça:

for i in *; do echo "$i"; echo ; cat "$i"; echo ; done ;

Je dirige généralement le chat dans un grep pour des informations spécifiques. 

4
MorpheousMarty

J'aime cette option 

for x in $(ls ./*.php); do echo $x; cat $x | grep -i 'menuItem'; done

La sortie ressemble à ceci:

./debug-things.php
./Facebook.Pixel.Code.php
./footer.trusted.seller.items.php
./GoogleAnalytics.php
./JivositeCode.php
./Live-Messenger.php
./mPopex.php
./NOTIFICATIONS-box.php
./reviewPopUp_Frame.php
            $('#top-nav-scroller-pos-<?=$active**MenuItem**;?>').addClass('active');
            gotTo**MenuItem**();
./Reviews-Frames-PopUps.php
./social.media.login.btns.php
./social-side-bar.php
./staticWalletsAlerst.php
./tmp-fix.php
./top-nav-scroller.php
$active**MenuItem** = '0';
        $active**MenuItem** = '1';
        $active**MenuItem** = '2';
        $active**MenuItem** = '3';
./Waiting-Overlay.php
./Yandex.Metrika.php
4
ch3ll0v3k

vous pouvez utiliser cette commande simple au lieu d'utiliser une boucle for,

ls -ltr | awk '{print $9}' | xargs head
3
Gagan

Si vous aimez les couleurs, essayez ceci:

for i in *; do echo; echo $'\e[33;1m'$i$'\e[0m'; cat $i; done | less -R

ou:

tail -n +1 * | grep -e $ -e '==.*'

ou: (avec le paquet 'multitail' installé)

multitail *
2
sjas

Voici un moyen très simple. Vous avez dit que vous voulez chatter, ce qui implique que vous voulez voir le fichier entier. Mais vous avez également besoin du nom de fichier imprimé.

Essaye ça

head -n99999999 * ou head -n99999999 file1.txt file2.txt file3.txt

J'espère que cela pourra aider

2
Trey Brister

Cette méthode imprimera le nom de fichier, puis le contenu du fichier:

tail -f file1.txt file2.txt

Sortie:

==> file1.txt <==
contents of file1.txt ...
contents of file1.txt ...

==> file2.txt <==
contents of file2.txt ...
contents of file2.txt ...
1
serenesat
find . -type f -exec cat {} \; -print
0
user5689319

Si vous voulez remplacer ceux qui sont laids ==> <== par autre chose

tail -n +1 *.txt | sed -e 's/==>/\n###/g' -e 's/<==/###/g' >> "files.txt"

explication:

tail -n +1 *.txt - affiche tous les fichiers du dossier avec en-tête

sed -e 's/==>/\n###/g' -e 's/<==/###/g' - remplacez ==> par nouvelle ligne + ### et <== par ### 

>> "files.txt" - tout écrire dans un fichier

0
boroboris

Si les fichiers portent tous le même nom ou peuvent être mis en correspondance par find, vous pouvez faire (par exemple):

find . -name create.sh | xargs tail -n +1

pour trouver, affichez le chemin de chaque fichier et sélectionnez-le.

0
drkvogel

Si vous voulez que le résultat soit dans le même format que la sortie souhaitée, vous pouvez essayer:

for file in `ls file{1..3}.txt`; \
do echo $file | cut -d '.' -f 1; \ 
cat $file  ; done;

Résultat: 

file1
bluemoongoodbeer
file2
awesomepossum
file3
hownowbrowncow

Vous pouvez mettre echo -e avant et après la coupe pour que vous ayez également l'espacement entre les lignes:

$ for file in `ls file{1..3}.txt`; do echo $file | cut -d '.' -f 1; echo -e; cat $file; echo -e  ; done;

Résultat:

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow
0
Fekete Sumér

Pour résoudre ce problème, j'utilise généralement la commande suivante:

$ cat file{1..3}.txt >> result.txt

C'est un moyen très pratique de concaténer des fichiers si le nombre de fichiers est assez grand.

0
Igor

Et la solution awk manquante est:

$ awk '(FNR==1){print ">> " FILENAME " <<"}1' *
0
kvantour
  • AIX 7.1 ksh

... glissant sur ceux qui ont déjà mentionné head travaille pour certains d'entre nous:

$ r head
head file*.txt
==> file1.txt <==
xxx
111

==> file2.txt <==
yyy
222
nyuk nyuk nyuk

==> file3.txt <==
zzz
$

Mon besoin est de lire la première ligne. comme indiqué, si vous voulez plus de 10 lignes, vous devrez ajouter des options (head -9999, etc.).

Désolé de poster un commentaire dérivé; Je n'ai pas assez de références dans la rue pour commenter/ajouter au commentaire de quelqu'un.

0
JustinKaisse