Il y a cet ensemble de lignes que j'aurais besoin de modifier
00:00 07:45 01._Alva 07:45 14:40 02._Whit_Cliffs 14:40 20:22 03._Ribcag_#1 20:22 25:04 04.__a_Oidipus
Après une correspondance (qui pourrait être le point), j'aurais besoin de remplacer les espaces qui suivent, (et seulement ceux qui suivent ) avec des tirets - ou des traits de soulignement _ .
sed -i 's/\(\.\)\(\s*\)/\1_/g' dummyfile2 | sed -i 's/\([[:alpha:]][[:space:]]\)\(\s*\)/_/g' dummyfile2
J'ai déjà essayé ce qui suit avec des résultats mitigés ...
dummyfile2 est le nom du fichier que j'utilise pour stocker les chaînes de texte
00:00 07:45 01._Alva 07:45 14:40 02._WhiteCliffs 14:40 20:22 03._Ribcage #1 20:22 25:04 04._I am Oidipus
donne le résultat:
sed -i 's/\(\.\)\(\s*\)/\1_/' dummyfile2 | sed -i 's/\(_\)\(\s*\)/\1_/' dummyfile2
J'ai aussi essayé de faire ce qui suit ...
00:00 07:45 01._Alva 07:45 14:40 02._White_Cliffs 14:40 20:22 03._Ribcage_#1 20:22 25:04 04._I_am_Oidipus
donne le résultat:
00:00 07:45 01. Alva 07:45 14:40 02. White Cliffs 14:40 20:22 03. Ribcage #1 20:22 25:04 04. I am Oidipus
Ce dernier était le le plus proche que j'ai pu trouver. (Mais ce n'est pas le résultat attendu.)
9 Réponses :
EDIT: Il semble que les autres solutions ne prennent en charge que l'espace en substituant le tout premier espace après .
ce qui suit prendra soin de tous les espaces.
pre> XXX
Si vous essayez dans sed
, alors ce qui suit peut vous aider. Vous n'avez pas besoin d'utiliser plusieurs commandes sed
.
awk '{sub(/\. +/,"._")} 1' Input_file 00:00 07:45 01._Alva 07:45 14:40 02._White Cliffs 14:40 20:22 03._Ribcage #1 20:22 25:04 04._I am Oidipus
Modifiez sed -E's / \. + / \ ._ / '
TO sed -E' s / \. + / \ ._ / g '
ci-dessus au cas où vous auriez plusieurs occurrences de .
(espaces) dans une ligne.
Si vous êtes d'accord avec awk
alors pourriez-vous essayer de suivre.
cat Input_file 00:00 07:45 01. Alva 07:45 14:40 02. White Cliffs 14:40 20:22 03. Ribcage #1 20:22 25:04 04. I am Oidipus
Si vous avez plusieurs occurrences de .
alors remplacez sub
avec gsub
dans la commande ci-dessus. La sortie sera la suivante.
00:00 07:45 01._Alva 07:45 14:40 02._White Cliffs 14:40 20:22 03._Ribcage #1 20:22 25:04 04._I am Oidipus
Code testé ci-dessus avec plusieurs espaces: Disons que nous avons plusieurs espaces après . alors aussi le code aboe fonctionnera. En supposant que votre fichier_entrée est comme suit.
awk '{sub(/\. +/,"._")} 1' Input_file
Ici, j'ai changé la dernière ligne en ajoutant plus d'espaces après .
, maintenant après l'exécution du code, il les remplacera avec un seul _
comme suit.
sed -E 's/\. +/\._/' Input_file 00:00 07:45 01._Alva 07:45 14:40 02._White Cliffs 14:40 20:22 03._Ribcage #1 20:22 25:04 04._I am Oidipus
awk
à la rescousse!
$ awk 'BEGIN{FS=OFS="."} {gsub(/ /,"_",$2)}1' file 00:00 07:45 01._Alva 07:45 14:40 02._White_Cliffs 14:40 20:22 03._Ribcage_#1 20:22 25:04 04._I_am_Oidipus
Cela échouerait si le texte après le premier .
contenait également des .
s et cela ressemble à du texte libre pour moi, donc je ne vois aucune raison de penser qu'il ne pourrait pas ' t contiennent .
s.
Avec GNU sed, vous pouvez le faire comme ceci:
sed -e ':a' -e 's/\(\.[^[:space:]]*\)[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\)/\1_\2/;' -e 'ta' file
Exemple (ajout d'un cas de bord):
$ cat file 00:00 07:45 01. Alva 07:45 14:40 02. White Cliffs 14:40 20:22 03. Ribcage #1 20:22 25:04 04. I am Oidipus 20:22 25:04 05.U re spe cial $ sed -E ':a;s/(\.\S*)\s+(\S+)/\1_\2/;ta' file 00:00 07:45 01._Alva 07:45 14:40 02._White_Cliffs 14:40 20:22 03._Ribcage_#1 20:22 25:04 04._I_am_Oidipus 20:22 25:04 05.U_re_spe_cial
POSIX sed conforme:
sed -E ':a;s/(\.\S*)\s+(\S+)/\1_\2/;ta'
Si vous êtes sûr qu'il n'y a pas d'espaces de fin dans vos lignes ou que vous voulez que les espaces de fin soient également remplacés, vous pouvez supprimer le deuxième groupe de capture ( ( ...)
ou \ (... \)
) et le \2
.
Vous n'avez pas besoin d'une deuxième référence arrière. Même sortie avec sed -E ': a; s / (\. \ S *) / \ 1 _ /; ta' file
.
@SLePort Il y a des espaces de queue dans les exemples de données d'OP, et évidemment OP ne veut pas que les espaces de queue soient remplacés par un trait de soulignement. Nous pouvons également interpréter l'intention de OP par le code (\ s * \)
à _
que OP veut remplacer plusieurs espaces consécutifs par un seul _
.
Il n'y a rien d'évident sur la façon dont OP veut gérer les espaces de fin. Et ce sont des exemples de données, pas un fichier source. Les espaces de fin peuvent être le résultat d'un copier-coller.
@SLePort C&P ne causera pas cela, il pourrait s'agir d'une erreur de formatage d'OP lors de la publication de la question. Quoi qu'il en soit, c'est le moyen le plus sûr de le faire.
Avec n'importe quel awk dans n'importe quel shell sur n'importe quelle boîte UNIX:
$ awk 'match($0,/([^.]+.)(.*)/,a){$0=a[1] gensub(/ /,"_","g",a[2])} 1' file 00:00 07:45 01._Alva 07:45 14:40 02._White_Cliffs 14:40 20:22 03._Ribcage_#1 20:22 25:04 04._I_am_Oidipus 20:22 25:04 05._here_is_a_dot._that_may_hurt._idk.
ou avec GNU awk pour le 3ème argument à match () et gensub ():
$ awk 'p=index($0,"."){tl=substr($0,p+1); gsub(/ /,"_",tl); $0=substr($0,1,p) tl} 1' file 00:00 07:45 01._Alva 07:45 14:40 02._White_Cliffs 14:40 20:22 03._Ribcage_#1 20:22 25:04 04._I_am_Oidipus
Avec sed (compatible POSIX):
sed -e :a -e 's/\(\.[^ ]*\) */\1_/;ta' file
Si vous souhaitez remplacer les espaces consécutifs par un seul _
:
sed -e :a -e 's/\(\.[^ ]*\) /\1_/;ta' file
Avec la modification de texte procédurale, vous pouvez y parvenir comme ceci:
forEach line { select (after ci ".") { findReplace ci " " "_" } }
Cela pourrait fonctionner pour vous (GNU sed):
sed -E 's/\s+\</_/3g' file
Remplacez le troisième groupe d'espaces avant un mot et au-delà par un _
. p >
Beaucoup de bonnes réponses. Je suis nouveau sur awk
mais voici une solution simple
{print $0}
Voici mon InputFile
00:00 07:45 01._Alva 07:45 14:40 02._White_Cliffs 14:40 20:22 03._Ribcage_#1 20:22 25:04 04._I_am_Oidipus
Utilisation de Perl
$ perl -pe ' s/(?:\S+)\. (.+)$/$x=$&;$x=~s! !_!g;$x/ge ' whitespace.txt 00:00 07:45 01._Alva 07:45 14:40 02._White_Cliffs 14:40 20:22 03._Ribcage_#1 20:22 25:04 04._I_am_Oidipus $
Plus simple: perl -pe's / \. \ K (. +) $ / $ 1 = ~ s {\ s +} {_} gr / ge 'whitespace.txt
(Commence à remplacer après le premier .
. Pour passer du dernier, s /.* \. \ K ... /
)
Veuillez consulter: Que dois-je faire lorsque quelqu'un répond à ma question?
Merci pour les conseils Tiw! J'y réfléchirai la prochaine fois que je posterai une question pour que je puisse la rendre plus facile à comprendre. À votre santé.