J'essaie de trouver comment répliquer une seule plage de lignes dans un fichier texte. La plage commence par une ligne unique dans le fichier, mais la plage se termine par une ligne qui peut exister à plusieurs endroits dans le fichier.
Voici quelques exemples d'entrée que je dois traiter :
I have no imagination so this sample text will Common be boring. But it does demonstrate the problem I am trying to solve. Common Hi mom! This is a unique line. And here is some more text that should be copied as well. Common Followed by text that should not be copied.
Les lignes que je dois dupliquer et modifier sont en gras pour les signaler ici.
La sortie dont j'ai besoin est :
I have no imagination so this sample text will Common be boring. But it does demonstrate the problem I am trying to solve. Common Hi mom! This is a changed line. And here is different more text that should be copied as well. Common This is a unique line. And here is some more text that should be copied as well. Common Followed by text that should not be copied.
La sortie supplémentaire est en gras pour le rendre clair.
J'ai besoin d'obtenir la plage de lignes commençant par la ligne :
This is a unique line
et se terminant par la ligne :
Common
Cette plage de lignes doit être insérée juste avant la plage de lignes d'origine. La copie de la plage de lignes correspondante devra être légèrement modifiée.
La ligne "Common" qui termine la plage peut elle-même apparaître à de nombreux endroits dans le fichier.
Je suis venu avec un awk
fonctionnel script, mais cela semble beaucoup plus compliqué que nécessaire. Mon awk
les compétences sont inexistantes.
/This is a unique line/{flag=1}
/Common/{
if (flag > 0) {
n=m;
sub("some","different",n);
sub("unique","changed",n);
print n "\n" $0 "\n" m;
m=""
};
flag=0
};
flag{
if (length(m) > 0) {
m=m "\n" $0
} else {
m=$0
}
}
!flag{ print }
Existe-t-il un moyen plus propre et moins verbeux d'implémenter cela? Je suis ouvert à d'autres options que awk
. Il doit simplement s'agir d'une commande standard disponible sur macOS.
Réponse acceptée :
awk '/This is a unique line/,/Common/{
H = H RS $0
if ( $0 ~ /Common/ ) {
g = H
sub("\n","",g)
sub("some","different",g)
sub("unique","changed",g)
$0 = g H
} else { next }
}1' inputfile
Voici le sed
code (j'ai montré dans la section Réponse) traduit en awk
.
Notez que, le code que vous avez, vous prenez la responsabilité d'activer/désactiver le awk
drapeau variable pour garder une trace des lignes. Mais alors que, awk
le fait déjà pour vous sous le capot exactement la même chose lorsque vous utilisez sa range
opérateur ,