Je souhaite supprimer la première ligne de plusieurs fichiers texte et la remplacer par une autre ligne. Y a-t-il un moyen de faire cela en utilisant le terminal?
Je sais utiliser vim, existe-t-il un moyen de l’automatiser avec? Je veux éviter de le faire manuellement (comme dans l'édition de chaque fichier individuellement).
Si possible, j'aimerais éviter d'installer de nouvelles bibliothèques (surtout pour quelque chose comme ce que je considère comme très simple - mais je peux me tromper).
Merci d'avance!
Vous pouvez utiliser sed
:
sed -i.bak '1s/^.*$/new line/' *.txt
Ceci remplacera la première ligne de tous les fichiers .txt
du répertoire en cours par le texte new line
et le changera pour répondre à vos besoins.
De plus, les fichiers originaux seront sauvegardés avec l'extension .bak
, si vous ne le souhaitez pas, utilisez simplement:
sed -i '1s/^.*$/new line/' *.txt
Bien, en utilisant vim
lui-même:
vim -Nesc 'bufdo call setline(1,"This is the replacement.") | wq' file1 file2 ...
Qu'est-ce que cela fait:
setline (n, text)
, eh bien, est une fonction qui définit la ligne n
sur text
.call
est nécessaire pour appeler des fonctions.bufdo
est utilisé pour répéter une commande sur des mémoires tampons (sans plage, il agit sur toutes les mémoires tampons).wq
enregistre et quitte le tampon. Nous devons faire cela avant de passer à la mémoire tampon suivante. Cette commande est donc chaînée à la commande call
à l'aide de |
.-c cmd
exécute cmd
est une commande en mode commande après le chargement du premier tampon.Nes
active le mode non compatible, silencieux et en mode ex, ce qui est préférable pour le traitement non interactif.Avantages:
setline
peut être n'importe quoi - un &
dans un texte de remplacement sed
peut avoir des effets inattendus.Quelques autres options:
awk
(nécessite une version relativement nouvelle de GNU awk
)
$ awk -i inplace -vline="new line" '(FNR==1){print line; next}1;' *.txt
Perl/Shell
$ for f in *txt; do
Perl -i -lne '$.==1 ? print "new line" : print' "$f"
done
Coquillage/coreutils
$ for f in *txt; do
( echo "new line"; tail -n+2 "$f" ) > foo && mv foo "$f";
done
Ce script fonctionnera comme vous l'avez demandé, plaçant les fichiers modifiés dans un nouveau répertoire sans modifier réellement les originaux.
d=/tmp/cooked
mkdir $d
for f in * #will match all files in current directory; adjust as desired
do
echo "This is the new 1st line" > /${d}/${f}
sed 1d ${f} >> /${d}/${f}
done
Les commandes queue et chat suffiraient facilement:
tail -n +1 $file > tmpfile
cat newfirstline tmpfile >$file
Enroulez-les dans une boucle appropriée et utilisez peut-être un fichier temporaire approprié et juste au lieu d'un nom de fichier temporaire codé en dur. Je pense que bash et d’autres shells ont une syntaxe pour créer des fichiers temporaires.
L'option -n de tail a deux interprétations selon que l'argument a un signe plus. S'il y a un signe plus, cela signifie que montrer la queue du fichier à partir de le numéro de ligne donné. Sinon, le nombre correspond au nombre de lignes, y compris la dernière ligne, que cette fin est supposée générer.
jEdit: Je l'utilise pour rechercher et remplacer en masse. Il est puissant avec la possibilité d'utiliser RegEx - Expressions régulières. Vous pouvez utiliser des fichiers d'un répertoire, spécifier des extensions de fichier, par exemple ".html", etc. Et, vous pouvez regarder les paramètres régionaux du changement de candidat en contexte, dans une interface graphique. jEdit est génial.
jEdit est disponible via le centre de logiciel Ubuntu.
Utiliser gawk
gawk -i inplace 'FNR==1 {$_="your_replacement"}; {print}' *.txt
Exemple
% cat foo.txt
1
2
3
4
% cat bar.txt
1
2
3
4
% gawk -i inplace 'FNR==1 {$_="your_replacement"}; {print}' *.txt
% cat foo.txt
your_replacement
2
3
4
% cat bar.txt
your_replacement
2
3
4