1
votes

Comment puis-je dupliquer une ligne contenant un mot spécifique et un certain nombre de lignes consécutives par exemple: en utilisant awk ou sed?

J'essaie de dupliquer et de manipuler des lignes spécifiques d'un fichier, en commençant par cet exemple.yaml:

game: 
  name: test
  ability: 1
  name: test
  ability: 1

Je veux dupliquer le name: test lignes name: test et ability: 1 , mais rien d'autre. Je ne souhaite pas utiliser de numéros de ligne pour sélectionner les lignes d'écriture, car les tailles et le contenu varient.

le résultat devrait être:

game: 
  name: test
  ability: 1

J'ai réussi à le résoudre avec:

awk '
/name: test/ {f=1}
/name: other/{
  f=0;
  for(i=1;i<=c;i++) print a[i]
}
f{ print; a[++c]=$0 }
!f{ print}
' example.yaml

Le problème est que le fichier yaml varie et que parfois name: test ability: 1 est la fin du fichier, ou parfois il est suivi par autre chose que name: other .

Une solution idéale devrait fonctionner pour les lignes qui suivent le modèle que je souhaite dupliquer:

game: 
  name: test
  ability: 1
  name: test
  ability: 1
  name: other 
  ability: 2

devrait être:

game:
  name: test
  ability: 1
  name: other
  ability: 2

Comment puis-je créer une solution plus générique qui n'utilise pas le modèle suivant celui que j'essaie de dupliquer?

Merci


2 commentaires

Vous dites want to duplicate the lines name:test and ability: play, but nothing else que votre sortie attendue n'a pas de ability: play ligne dedans? Pourriez-vous s'il vous plaît clarifier plus à ce sujet dans votre question.


Utilisez un langage de programmation avec une bibliothèque yaml, comme Python


3 Réponses :


1
votes

Dans sed c'est simple:

sed '/name: test/{N;p;}' filename

En gros, cela dit: "si la ligne contient name: test , alors lisez également la ligne suivante, puis imprimez-les une fois de plus".


1 commentaires

Merci beaucoup! Celui-ci semble être le plus facile à comprendre et fonctionne bien.



1
votes

Cela pourrait fonctionner pour vous (GNU sed):

sed '/\<name: test$/{/\<ability: 1$/p}' file

Si une ligne se termine par name: test et la ability: 1 suivante se termine ability: 1 , dupliquez ces lignes.


0 commentaires

0
votes

Alternative à Awk:

awk '/name: test/ { line=$0 } /ability/ && line!="" { $0=$0"\n"line"\n"$0;line=""}1' file

Si la ligne "nom: test" est trouvée, définissez la ligne variable égale à la ligne de lecture (0 $), puis lorsque nous trouvons que la capacité de ligne et la ligne ne sont pas égales à "" (le nom est test), définissez la ligne de lecture $ 0 égale à la ligne existante puis un retour chariot, la variable de ligne (nom: test) puis la ligne existante à nouveau. Réinitialisez la variable de ligne à vide. Utilisez l'aiguille courte 1 pour imprimer la ligne.


0 commentaires