6
votes

AWK: Y a-t-il un moyen de se mettre en forme de fs si celui-ci est une regex?

dans awk, le séparateur de champ (ou d'enregistrement) fs code> (ou rs code>) peut être défini comme une expression régulière. Cela fonctionne bien pour obtenir un champ individuel, mais une fois que vous avez défini un de ces champs, les séparateurs de champ sont "partis".

echo "a|b-c|d" | awk '... {$3="z"}1'
a|b-z|d


0 commentaires

3 Réponses :


3
votes

awk réécrit chaque enregistrement à l'aide de of si vous modifiez une valeur classée à l'aide de $ n = (où n est numéro de champ) .

Puisque vous utilisez plusieurs délimiteurs dans fs , vous ne pouvez pas utiliser of = fs .

Si vous avez gnu awk < / code> Vous pouvez ensuite utiliser la solution basée sur xxx

Vous pouvez utiliser sed : xxx


2 commentaires

Belle utilisation de RT !


Je pense que vous pouvez optimiser la solution SED comme SED -E 'S / ^ (([^ | -] + [| -]) {2}) [^ | -] + / \ 1Z /' <<<< " $ s " ... capture les deux premiers champs avec des séparateurs, puis remplace le troisième champ sans gêner ce qui se situe au-delà et incl. Troisième séparateur ...



5
votes

Comme vous l'avez déjà mentionné, il n'ya aucun moyen de définir of de manière dynamique sur le fs utilisé sur tous les cas. Si la regex était dans RS au lieu de fs , vous pouvez utiliser rt (en fait, je viens de voir la réponse d'Anubhava fait ceci, sympa!) .

Cependant, il existe une autre façon si vous avez GNU AWK: comme on le voit dans Remplacement de la colonne avec AWK, avec le retenue du format (ed La réponse de Morton) , vous pouvez utiliser Split () et, spécialement, son 4ème argument. Pourquoi? Parce que cela stocke le séparateur entre chaque tranche: xxx

comme une doublure: xxx

Split (chaîne, tableau [ SEPS]]])

Diviser la chaîne en morceaux séparés par le champ de champ et stockez les morceaux dans la matrice et les chaînes de séparateur dans la matrice SEPS. La première pièce est stockée dans Array 1 , la deuxième pièce dans le tableau 2 , et ainsi de suite. La valeur de la chaîne de la troisième argument, champ FieldSeP, est une REGEXP décrivant où scinder la chaîne (beaucoup comme FS peut être une regexp décrivant où diviser les enregistrements d'entrée). Si FieldSeP est omis, la valeur de FS est utilisée. Split () renvoie le nombre d'éléments créés. SEPS est une extension GAWK, avec des SEP [I] étant la chaîne de séparation entre la matrice [I] et le tableau [i + 1] . Si FieldSeeP est un seul espace, tout le capital de tête passe dans les SEPS [0] et tout blancheur de fuite passe en SEPS [n], où n est la valeur de retour de Split () (c.-à-d. Le nombre d'éléments dans la matrice). < / p>


2 commentaires

Très bon Split Solution basée sur SEPS comme 4ème argument. Espérons que OP a gnu awk.


Je suppose qu'il n'y a pas besoin de changer fs ici; Vous pouvez également simplement utiliser / [| -] / comme troisième argument sur divisé .



0
votes

Étant donné que vous n'avez clairement pas besoin de travailler les champs, procédez simplement à 0 $ d'autres manières, comme ci-dessous avec sous : xxx


2 commentaires

Les valeurs que j'ai prises dans l'exemple sont factices factices. Un simple sous ne fonctionnerait pas dans un cas générique où, par exemple, vous définissez 3 $ = 1 $ 1 $ 2 (et non une valeur codée (et non une valeur codée).


Je pensais donc que j'ai décidé de laisser cela comme un reste pour les futures générations de maîtres des langues archaïques.