J'ai donc une chaîne qui se compose de deux mots, où je veux imprimer les deux mots séparément dans awk (en fait gawk). La chaîne peut ressembler à ceci,
Sample input: str="ab cd" Sample output: "ab and cd"
Donc je J'ai cherché sur le Web et tout ce que je propose, ce sont des exemples sur la façon d'analyser cela à partir d'un fichier. Cependant, cela ne fonctionne pas dans mon cas. Ce serait assez facile à faire en perl; Quelque chose comme ça,
my $str="ab cd"; $str =~/(.+)\s(.+)/; print "$1 and $2\n";
Cependant, awk n'a pas ce regroupement. Le problème est que je dois conserver l'entrée, donc split ()
, sub ()
, ... n'aideront pas. Cela fonctionnerait probablement avec match ()
, mais ce n'est pas si joli.
Quelqu'un qui a une meilleure idée?
str="ab cd"
Notez que le "et" ne fait pas partie de la correspondance, mais il devrait être possible d'imprimer cette chaîne.
BR Patrik
4 Réponses :
GNU awk:
$ awk -v str="ab cd" 'BEGIN{print gensub(/(.+)\s(.+)/, "\\1 and \\2\n", 1, str)}' ab and cd
Remplacez par -v str = "$ var"
si vous souhaitez transférer une valeur de variable vers awk
.
Cela semble fonctionner. J'ai en fait deux chaînes différentes (même format) et je veux générer une chaîne qui ressemble à quelque chose comme "$ 1: $ 2_1, $ 2_2" où $ 2_ est un pseudo-code pour la première et la deuxième chaîne. Quoi qu'il en soit, cela est possible avec quelques modifications mineures ( gensub (/ (. +) \ S (. +) \ S (. +) \ S (. +) /, "\\ 1: \\ 2 - > \\ 4 ", 1, str" "str2)
). Sérieusement, ce doit être la réponse la plus rapide que j'aie jamais eue. Merci!
@patrik Fyi: Le regex d'Awk n'est pas aussi puissant que celui de perl, c'est un sur-ensemble de ERE. Cela pourrait aider.
gnu awk, utilisez la forme à 3 arguments de la fonction match ()
foo and bar
awk -v str="foo bar" 'BEGIN { if (match(str, /^(.+)[[:space:]]+(.+)/, m)) { print m[1], "and", m[2] } }'
Scinder la chaîne avec un espace blanc en un tableau:
ab and cd
Sortie:
awk -v string="ab cd" 'BEGIN{split(string,array," "); print array[1],"and",array[2]}'
Le troisième argument split
n'est pas nécessaire ici.
@karakfa pouvez-vous expliquer cela? Dans mon cas, la chaîne d'origine doit être préservée. Cela pourrait également être possible avec votre solution, donc ce serait bien de le consulter pour référence future
split n'endommagera pas la chaîne d'origine, mais ici ma note est que le délimiteur par défaut n'a pas besoin d'être spécifié comme troisième argument.
idk ce que vous entendez par l'un des Cependant, awk n'a pas ce regroupement. Le problème est que j'ai besoin de conserver l'entrée, donc split (), sub (), ... n'aideront pas. Cela fonctionnerait probablement avec match (), mais ce n'est pas si joli.
L'équivalent gawk du code perl dans votre question:
awk 'BEGIN { str="ab cd" match(str,/(.+)\s(.+)/,a) print a[1], "and", a[2] }' ab and cd
line pour la ligne, serait:
str="ab cd" match(str,/(.+)\s(.+)/,a) print a[1], "and", a[2]
par exemple:
my $str="ab cd"; $str =~/(.+)\s(.+)/; print "$1 and $2\n";
Je ne sais pas si c'est la meilleure façon de faire quoi que vous essayiez vraiment de faire puisque je ne sais pas ce que vous essayez vraiment de faire!
Pourriez-vous s'il vous plaît poster un échantillon de la sortie attendue dans votre message et nous le faire savoir alors.
Si vous voulez simplement l'imprimer (je ne sais pas si je l'ai correctement). Essayez comme
echo "$ str" | awk '{print $ 1, $ 2}'
Ou si vous voulez passer la variable shell àawk
en tant que variable, essayezawk -v str = "$ str" 'BEGIN { split (str, array, ""); print array [1], array [2]}
dans la 2ème solution, vous ne devez PAS mentionner de Input_file car je n'ai utilisé que la sectionBEGIN
ici , fais-moi savoir?Pouvez-vous expliquer pourquoi la division et la correspondance sont insuffisantes?
Si vous n'avez qu'une seule chaîne, pas besoin de awk: str = "ab cd"; printf '% s et% s \ n' $ str. S'il s'agit d'un fichier, vous devez en dire plus.