1
votes

Fractionner la 2e occurrence du motif du texte de style chameau dans sed

J'essaie de créer une table de chaînes de clés et de valeurs pour une application Mac en utilisant sed et awk. Jusqu'à présent, je suis arrivé au point d'avoir des lignes comme:

"exif:DateTimeOriginal" = DateTimeOriginal:\t";

Je veux faire une dernière étape pour obtenir:

sed 's/\([A-Z]\)/ \1/2g'

En d'autres termes, divisez la deuxième occurrence du texte de chameau. J'ai vu sed comme ceci:

sed 's/\([A-Z]\)/ \1/g'

Ce qui le ferait globalement, puis ferait simplement la 2ème occurrence avec:

"exif:DateTimeOriginal" = "Date Time Original:\t";

Ou est-ce la 3e occurrence. Cependant, malheureusement sur macos, vous ne pouvez pas combiner un nombre avec la commande g.

Alors, y a-t-il une autre façon de faire cela?

BTW, je pourrais faire en sorte que vous commenciez avec:

"exif:DateTimeOriginal" = "DateTimeOriginal:\t";

Autrement dit, laissez de côté la citation de début du texte de chameau, de sorte que si un espace de début est ajouté en divisant le texte de chameau, il soit ajouté après le = ce qui n'aurait pas d'importance. Ajoutez ensuite la citation de début une fois le texte du chameau divisé.


0 commentaires

5 Réponses :


1
votes

avec GNU awk (pas la valeur par défaut pour votre système d'exploitation).

$ awk -F'"' -v OFS='"' '{$4=gensub(/([^A-Z])([A-Z])/,"\\1 \\2","g",$4)}1' file

"exif:DateTimeOriginal" = "Date Time Original:\t";

vous aurez peut-être besoin de classes de caractères [: lower:] ou [: upper:] selon vos paramètres régionaux.


2 commentaires

Merci, je vais jeter un oeil là-dessus. Une autre façon pourrait être de commencer avec la chaîne d'origine qui est: DateTimeOriginal, divisez-la et enregistrez-la dans un fichier temporaire, puis fusionnez-la avec la première partie de la chaîne: "exif: DateTimeOriginal" =.


@JimMerkel non, c'est une tâche triviale, vous n'avez pas besoin de fichiers temporaires pour l'accomplir.



1
votes

Avec n'importe quel awk POSIX:

$ awk 'BEGIN{FS=OFS="\""} {gsub(/[[:upper:]]/," &",$4); sub(/^ /,"",$4)} 1' file
"exif:DateTimeOriginal" = "Date Time Original:\t";


1 commentaires

Merci. C'est trivial ou non selon la fréquence à laquelle vous devez développer un script. Je développe un script peut-être tous les quelques mois environ. Je dois revenir en arrière et RTFM pour comprendre comment écrire un script pour faire une chose particulière.



1
votes

Voici comment vous pouvez le faire avec sed:

sed -E -e ':a' -e 's/^([^=]+)= (.*)([a-z])([A-Z])/\1= \2\3 \4/' -e 'ta'

L'idée est d'appliquer des substitutions répétées (: a et ta ) où vous faites correspondre la partie que vous ne souhaitez pas modifier ( [^ =] + ) puis insérez un espace entre une lettre minuscule suivie d'une lettre majuscule ( [az] [ AZ] ) dans le reste.


2 commentaires

J'ai fini par utiliser la méthode inélégante des fichiers temporaires comme mentionné ci-dessus, puis en fusionnant les fichiers avec unix merge.


Je devrais dire que j'ai utilisé la commande Unix paste: paste -d "" file1 file2> outputFile.



0
votes

Utilisation de Perl

$ echo '"exif:DateTimeOriginal" = DateTimeOriginal:\t"' | perl -F'"' -lane ' $F[2]=~s/(?=[A-Z])/ /g;$F[2]=~s/\s+=\s+/=\"/g; print "\"$F[1]\"$F[2]\"" '
"exif:DateTimeOriginal"="Date Time Original:    "
$


0 commentaires

1
votes

Cela pourrait fonctionner pour vous (GNU sed):

sed 'h;s/\B[[:upper:]]/ &/g;H;x;s/=.*=/=/' file

Faites une copie de la ligne courante.

Insérez un espace avant toutes les majuscules dans un mot.

Ajoutez le résultat à la ligne d'origine.

Supprimez la queue de la ligne d'origine et la tête du résultat.


0 commentaires