Je trouve une commande bash pour un remplacement conditionnel avec offset. Les articles existants que j'ai trouvés sont des remplacements conditionnels sans offset ou avec un offset fixe .
Tâche: Si uid
contient 8964
, puis insérez la ligne FORBIDDEN
avant DOB
.
Chaque fichier TXT ci-dessous représente un utilisateur, et il contient (dans le ordre suivant)
uid
DOB
J'espère pouvoir transformer les fichiers suivants
sed: -e expression #1, char 0: unmatched `{'
en
sed '/^uid: [0-9]*8964[0-9]*$/{n;/^DOB: .*$/{iFORBIDDEN}}' file*.txt
Mon essai:
Si uid
contient 8964
, alors faites une deuxième correspondance avec DOB
et insérez FORBIDDEN
ci-dessus DOB
.
# file1.txt (uid doens't match 8964) admin: false uid: 123456 happy movie DOB: 6543-02-10 lorem ipsum seo varis lireccuni paccem noba sako # file2.txt (uid matches 8964) citizen: true hasSEAcct: true uid: 289641 joyful hearty final debug Juno XYus magazine FORBIDDEN DOB: 1234-05-06 saadi torem lopez dupont
Cela me donne une erreur {
inégalée.
# file1.txt (uid doens't match 8964) admin: false uid: 123456 happy movie DOB: 6543-02-10 lorem ipsum seo varis lireccuni paccem noba sako # file2.txt (uid matches 8964) citizen: true hasSEAcct: true uid: 289641 joyful hearty final debug Juno XYus magazine DOB: 1234-05-06 saadi torem lopez dupont
3 Réponses :
$ awk -v RS='' '/uid: [0-9]*8964/{sub(/DOB/, "FORBIDDEN\nDOB")} 1' file
Merci de répondre. Ça marche vraiment. Cependant, je ne connais pas awk
. Où puis-je apprendre les bases? Je ne peux trouver "drapeau" dans ce fameux awk
tutoriel . Pourquoi FORBIDDEN
est imprimé avant DOB
et pas après ? J'ai essayé de remplacer 1
par 2
ou 0.5
à la ligne # 3
. Que signifie 1
?
Ne soyez pas intimidé, c'est juste le niveau supérieur de Sed. Awk est également un outil pédagogique précieux pour la logique C
, alors lisez man gawk
. 1
(ou plus) est vrai, tandis que 0
(ou nul) est faux. «drapeau» n'est pas un terme officiel, juste l'idée d'une variable booléenne que nous activons ou désactivons pour garder un œil sur une condition. Lorsqu'il y a une condition sans {action}
, comme 1
tout seul, awk effectue le comportement par défaut, qui est {print $ 0}
( imprimer toute la ligne).
Merci pour la réponse. J'ai parcouru man awk
sur Ubuntu, et j'ai une meilleure idée de mawk
. Si j'échange # 2
et # 3
, j'obtiens FORBIDDEN
après DOB
.
À mon avis, c'est un bon cas d'utilisation de sed.
Voici une solution GNU sed avec quelques explications:
ⶠgsed -e '/^uid:.*8964/,/DOB/{/DOB/i FORBIDDEN' -e '}' FILE*
Test: p >
ⶠgsed -f script.sed FILE1 admin: false uid: 123456 happy movie DOB: 6543-02-10 lorem ipsum seo varis lireccuni paccem noba sako
ⶠgsed -f script.sed FILE2 citizen: true hasSEAcct: true uid: 289641 joyful hearty final debug Juno XYus magazine FORBIDDEN DOB: 1234-05-06 saadi torem lopez dupont
Ou sur une seule ligne:
# script.sed /^uid:.*8964/,/DOB/ { # Search only inside this range, if it exists. /DOB/i FORBIDDEN # Insert FORBIDDEN before the line matching /DOB/. }
Bonne réponse! En ce qui concerne la commande à une ligne, y a-t-il une raison à une telle séparation? Je sais seulement que si les trois expressions sont réunies, il y aura une erreur {
inégalée.
@ GNUSupporter8964 民主 女神 地下 教會, et bonne question aussi au fait. Les multiples -e
s sont là car la commande i
s'attend à ce que des "lignes" de texte suivent. AFAIK, la chaîne à insérer doit être suivie d'un caractère de nouvelle ligne, mais le }
doit encore fermer le bloc {
.. }
. Je ne connais donc pas d'autre moyen de tout mettre sur une seule ligne que d'utiliser plusieurs -e
s.
Voir aussi les exemples ici gnu.org/software/sed/manual /sed.html#Other-Commands
essayé sur gnu sed
sed -Ee '/^uid:\s*\w*8964\w*$/{n;/^DOB:/iFORBIDDEN' -e '}' file*.txt