2
votes

Sed insérer une chaîne à la première ligne du fichier si la première ligne correspond au modèle

J'ai une question sed à laquelle je n'ai pas encore trouvé de réponse:

J'ai un tas de fichiers, certains d'entre eux commencent par la chaîne ### et d'autres non. Dans chaque fichier commençant par ### , je voudrais insérer une chaîne de plusieurs lignes avant la première ligne actuelle.

f.e. Si un fichier ressemble à

my
multi
line
string

### the first line

abc cba jfkdslfjslkd

Je veux que la chaîne multi-lignes soit insérée en haut

### the first line

abc cba jfkdslfjslkd

Rien d'autre dans le fichier devrait être modifié.

Si un fichier ne commence pas par ### , je ne veux pas le modifier.


0 commentaires

3 Réponses :


2
votes

Utilisation de sed

Commençons par définir votre chaîne:

$ s='my\nmulti\nline\nstring\n'
$ awk -v string="$s" 'NR==1 && /^###/ {print string} 1' File
my
multi
line
string

### the first line

abc cba jfkdslfjslkd

Maintenant, exécutons une commande sed:

$ sed "1s/^###/$s&/" File
my
multi
line
string

### the first line

abc cba jfkdslfjslkd

Comment ça marche:

  • 1s / ancien / nouveau / remplace nouveau par ancien mais seulement si old apparaît sur la première ligne.

  • 1s / ^ ### / $ s & / remplace la chaîne $ s devant ### si le la première ligne commence par ###.

Attention: La chaîne s ne doit contenir aucun caractère sed-actif. Si la chaîne s n'est pas sous votre contrôle, il s'agit d'une violation de sécurité.

Utiliser awk

Awk gère judicieusement les variables et cela évite la sécurité problème.

$ s='my\nmulti\nline\nstring\n\n'

2 commentaires

Je crois (votre opinion est la bienvenue) ma réponse évite le problème de sécurité avec sed?


@AlexHarvey Dans votre réponse, essayez string = $ '\ n /./ w newfile' et vous vous retrouverez avec un nouveau fichier sur votre système de fichiers.



0
votes

Cela peut être une solution plus simple dans sed:

Entrée:

â–¶ gsed -e '1{/^###/i\' -e "$string" -e '}' FILE
my
multi
line
string

### the first line

abc cba jfkdslfjslkd

### other lines"

Solution:

â–¶ string='my\nmulti\nline\nstring\n'
â–¶ cat FILE 
### the first line

abc cba jfkdslfjslkd

### other lines

Explication :

  • L'utilisation de plusieurs -e nous permet d'éviter d'interpoler des chaînes dans la commande sed.
  • La forme alternative GNU de i \ comme indiqué dans le manuel GNU.


0 commentaires

0
votes

essayé sur gnu sed et bash

$ a='my\nmulti\nline\nstring'; echo -e $a
my
multi
line
string

$  sed -Ee "0,/^###/{/^###/i$a" -e '}' file*

my
multi
line
string
### the first line

abc cba jfkdslfjslkd


0 commentaires