J'ai un fichier avec un mot différent dans chaque ligne. Mon objectif est de remplacer le premier caractère à une lettre majuscule et de remplacer le 3ème caractère à "#". P>
Par exemple: le football sera échangé vers -> FOO # Ball P>
J'ai essayé de penser à utiliser awk et sed.it ne m'a pas aidé depuis (à ma connaissance) SED a besoin d'une entrée exacte du caractère et de l'AWK peut imprimer le caractère souhaité mais ne le modifie pas. P>
7 Réponses :
avec GNU SED et deux sortie: p> s code> s code> s:
Foo#ball
Les réponses de Cyrus 'ou Potong sont les préférées. (Pour Linux ou Systèmes avec GNU SED à cause de \ u ou \ u.)
Il s'agit simplement d'une solution supplémentaire avec AWK car vous l'avez mentionnée et utilisée aussi AWK Tag: P>
$ echo 'football'|awk '{a=substr($0,1,1);b=substr($0,2,2);c=substr($0,5);print toupper(a)b"#"c}' Foo#ball
Laissez-moi l'appeller différemment :-): afaik je n'utilise aucune "extension GNU". Ainsi, la solution doit être la plus compatible.
Merci. Tout d'abord, je n'étais pas sûr de la compatibilité et de la seconde que je n'étais pas sûre de la langue (anglais). :-) Mise à jour.
Ceci devrait fonctionner avec n'importe quelle version de Remarque: Si un mot est inférieur à 3 caractères, comme awk code>:
code> em>, il sera imprimé sous le nom
# code> p> p>
"Parole différent dans chaque ligne": cela signifie qu'un seul mot est utilisé par ligne. Votre solution fonctionne également sur plusieurs mots d'une ligne.
Vrai. Eh bien, cela fonctionne également s'il n'y a qu'un seul mot dans chaque ligne. :)
Avec BASH, vous pouvez utiliser uniquement les expansions de paramètres pour accomplir la tâche. Par exemple, si vous lisez chaque ligne dans la variable exemple de fichier d'entrée fort> p> p> XXX PRE> ligne code>, vous pouvez faire:
$ while read -r line; do line="${line^}"; echo "${line:0:3}#${line:4}"; done < file
Foo#ball
Soc#er
Bas#ball
Le Lire code> seul le rendra extrêmement lent par rapport à une solution SED ou AWK, voir Unix.stackexchange. COM / Q / 169716/133219 . Toujours citer vos variables sauf si vous besoin b> pour faire quelque chose que nécessite b> qu'ils doivent être inclus - voir mywiki.woolgedge.org/quotes . Dans ce cas, même si nous supposons qu'il n'y a pas d'espaces dans l'entrée, vous obtiendrez des résultats malheureux si l'entrée contenait des caractères de globe qui vient de correspondre à des noms de fichiers locaux.
Oui, cela ne fait que environ 100 000 lignes par seconde (avec SSD), donc si votre fichier est des millions, vous voudrez quelque chose de plus rapidement. Si vous avez affaire à 1000 lignes ou moins, c'est dans le bruit. D'accord sur la citation, cela venait d'omettre en raison de l'entrée d'un mot - mais cela devrait être là pour la généralisation.
Sur ma machine, il faut 4,81 secondes pour 100 000 lignes :-). La solution GNU SED de GNU de FWIW Potong (sans surprise, car c'est ce que SED est le meilleur pour) a pris 0,17 seconde tandis que mon GNU awk one a pris 0,98 sec et Reichharts Posix Awk a pris seulement 0,22 sec. D'accord sur le "Si vous traitez avec 1000 lignes ou moins ..." Mais vous chercheriez ensuite une autre raison de l'utiliser sur SED ou Awk. Je n'ai que commentaire seulement parce que vous avez dit lorsque l'utilisation est limitée aux produits, il ne tombe pas trop loin derrière code> car il tombe toujours très loin derrière.
J'ai utilisé / usr / lib / dict / mots code> pour le test
305089-mots code> (
3.481s code> total). Je ne dis pas que c'est plus rapide, vous le savez. Le
"pas trop loin derrière" code> pourrait mieux être exprimé comme
"pas aussi mauvais que d'appeler un utilitaire supplémentaire à l'intérieur de la boucle" code>.
awk code> solution
(1,833s Total) code> Même fichier, exécuté dans SUBSHELL redirigé vers
/ dev / null code>.
Cela pourrait fonctionner pour vous (GNU SED):
sed 's/\(...\)./\u\1#/' file
avec GNU AWK pour le 3ème Arg pour correspondre ():
$ echo 'football' | awk 'match($0,/(.)(..).(.*)/,a){$0=toupper(a[1]) a[2] "#" a[3]} 1' Foo#ball
Merci. Dans ce cas, il est un peu trop exclu que si cela est vraiment tout ce qui doit être fait, je devrais aller avec @potongs Si vous avez des outils GNU et si vous n'êtes pas alors @reichharts .
Si vos données dans le fichier 'D', essayé sur GNU SED:
sed -E 's/^(\w)(\w\w)\w/\U\1\E\2#/' d
Il est difficile de dire ce qui ne va pas avec votre code parce que vous ne l'avez pas fourni ni les erreurs que vous avez rencontrées. Voir également Comment créer un exemple minimal, complet et vérifiable .
SED a besoin d'une entrée exacte du caractère code>? Complètement le contraire, SED ne peut pas fonctionner sur une entrée exacte du personnage - voir Stackoverflow.com/q/29613304/1745001 pour les cerceaux Vous devez sauter pour que SED agisse comme s'il utilisait des chaînes littérales.