Comment insérer un texte au début d'un fichier?
jusqu'à présent, j'ai été en mesure de trouver comment ajouter une ligne au début d'un fichier, mais ce n'est pas exactement ce que je veux. Je vais le montrer sur un exemple
contenu du Fichier
some text at the beginning
résultat
<added text> some text at the beginning
c'est similaire mais je ne veux pas créer de nouvelle ligne avec elle...
j'aimerais le faire avec sed
si possible.
12 réponses
sed
peut fonctionner à une adresse:
$ sed -i '1s/^/<added text> /' file
Qu'est-ce magique 1s
que vous voyez sur chaque réponse ici? adresse de ligne! .
Voulez ajouter <added text>
sur les 10 premières lignes?
$ sed -i '1,10s/^/<added text> /' file
ou vous pouvez utiliser Command Grouping
:
$ { echo -n '<added text> '; cat file; } >file.new
$ mv file{.new,}
si le fichier n'est qu'une ligne, vous pouvez utiliser:
sed 's/^/insert this /' oldfile > newfile
S'il y a plus d'une ligne. un de:
sed '1s/^/insert this /' oldfile > newfile
sed '1,1s/^/insert this /' oldfile > newfile
j'ai inclus ce dernier pour que vous sachiez faire des gammes de lignes. Ces deux "remplacer" la ligne de départ marqueur sur leur touchés lignes contenant le texte que vous souhaitez insérer. Vous pouvez également (en supposant que votre sed
est assez moderne) utiliser:
sed -i 'whatever command you choose' filename
pour faire la modification sur place.
Si vous voulez ajouter une ligne au début d'un fichier, vous devez ajouter \n
à la fin de la chaîne de la meilleure solution ci-dessus.
La meilleure solution permettra d'ajouter la chaîne, mais à la chaîne, il ne sera pas ajouter une ligne à la fin d'un fichier.
sed -i '1s/^/your text\n/' file
vous pouvez utiliser cat -
printf '%s' "some text at the beginning" | cat - filename
Notez que sur OS X, sed -i <pattern> file
, échoue. Cependant, si vous fournissez une extension de sauvegarde, sed -i old <pattern> file
, alors file
est modifié en place alors que file.old
est créé. Vous pouvez ensuite supprimer file.old
dans votre script.
problème: tag un fichier, en haut du fichier, avec le nom de base du répertoire parent.
c'est-à-dire, au lieu de
/mnt/Vancouver/Programming/file1
tag sommet de la file1
avec Programming
.
SOLUTION 1 -- non-empty files:
bn=${PWD##*/} ## bn: basename
sed -i '1s/^/'"$bn"'\n/' <file>
1s
place le texte à la ligne 1 du fichier.
SOLUTION 2 -- fichiers vides ou non vides:
la commande sed
ci-dessus ne fonctionne pas sur les fichiers vides. Voici une solution, basée sur https://superuser.com/questions/246837/how-do-i-add-text-to-the-beginning-of-a-file-in-bash/246841#246841
printf "${PWD##*/}\n" | cat - <file> > temp && mv -f temp <file>
notez que le -
dans la commande cat est requis (lit entrée standard: voir man cat
pour plus d'informations). Ici, je crois, c'est nécessaire pour prendre la sortie de la déclaration printf (à STDIN), et cat that et le fichier à temp ... Voir aussi l'explication au bas de http://www.linfo.org/cat.html .
j'ai aussi ajouté -f
à la commande mv
, pour éviter d'être demandé des confirmations lors de la réécriture de fichiers.
répéter au cours d'un répertoire:
for file in *; do printf "${PWD##*/}\n" | cat - $file > temp && mv -f temp $file; done
Notez aussi que cela cassera sur les chemins avec des espaces; il y a des solutions, ailleurs (par exemple globbing de fichiers, ou des solutions de type find . -type f ...
) pour ceux-ci.
ADDENDUM: Re: mon dernier commentaire, ce script va vous permettre de vous répéter au cours des répertoires avec des espaces dans les chemins:
#!/bin/bash
## /q/how-to-loop-through-a-directory-recursively-to-delete-files-with-certain-extensions-69426/"/mnt/Vancouver/Programming/data/claws-test/corpus test/"
# https://superuser.com/questions/716001/how-can-i-get-files-with-numeric-names-using-ls-command
# FILES=$(find $IN -type f -regex ".*/[0-9]*") ## recursive; numeric filenames only
FILES=$(find $IN -type f -regex ".*/[0-9 ]*") ## recursive; numeric filenames only (may include spaces)
# echo '$FILES:' ## single-quoted, (literally) prints: $FILES:
# echo "$FILES" ## double-quoted, prints path/, filename (one per line)
# ----------------------------------------------------------------------------
# MAIN LOOP:
for f in $FILES
do
# Tag top of file with basename of current dir:
printf "[top] Tag: ${PWD##*/}\n\n" | cat - $f > temp && mv -f temp $f
# Tag bottom of file with basename of current dir:
printf "\n[bottom] Tag: ${PWD##*/}\n" >> $f
done
unset IFS; set +f
echo -n "text to insert " ;tac filename.txt| tac > newfilename.txt
le premier tac
pipes le fichier à l'envers (dernière ligne en premier) de sorte que le" texte à insérer " apparaît en dernier. Le 2ème tac
l'enveloppe encore une fois de sorte que la ligne insérée est au début et le fichier original est dans son ordre d'origine.
pour ajouter une ligne en haut du fichier:
sed -i '1iText to add\'
juste pour le plaisir, voici une solution en utilisant ed
qui n'a pas le problème de ne pas travailler sur un fichier vide. Vous pouvez le mettre dans un script shell comme n'importe quelle autre réponse à cette question.
ed Test <<EOF
a
.
0i
<added text>
.
1,+1 j
$ g/^$/d
wq
EOF
Le script ci-dessus, ajoute le texte à insérer à la première ligne, puis rejoint la première et la deuxième ligne. Pour éviter ed sortant sur erreur avec une jointure invalide, il crée d'abord une ligne vide à la fin du fichier et le supprime plus tard si elle encore exister.
Limitations: ce script ne fonctionne pas si <added text>
est exactement égal à une période unique.
il y a un moyen très facile:
echo "your header" > headerFile.txt
cat yourFile >> headerFile.txt