Howto diviser une chaîne sur un multi-caractère délimiteur dans le bash?
Pourquoi ne pas travailler les suivantes bash code?
for i in $( echo "emmbbmmaaddsb" | split -t "mm" )
do
echo "$i"
done
résultat attendu:
e
bb
aaddsb
- ...hein? Ce n'est pas ce
split
le fait. Comme dans complètement sans rapport avec sa fonction réelle. - Voulez-vous savoir comment découper une chaîne de caractères arbitraire arbitraire de caractères multi-séparateur en bash? Pourquoi pas de modifier une question à poser que, au contraire, si c'est ce que vous voulez vraiment le savoir?
- Donc, ce n'est fractionner faire à votre avis?
split
de diviser un fichier en un tas de petits fichiers. Pas de noms écrits sur la sortie standard, comme votre script attend, mais de vrais fichiers. Et-t
donne un caractère unique qu'il utilise pour déterminer si les dossiers de début et de fin, et donc de faire des fentes sur enregistrements.- Ne fonctionne pas avec de simples caractères.
- Bien sûr que non, PARCE que VOUS attendez des NOMS ÉCRITS sur la sortie standard STDOUT. Je vous ai déjà dit qu'il ne veut pas écrire les noms sur la sortie standard stdout.
- Dans la page de manuel de split lecture à partir d'un tuyau est mentionné
- Si rien n'est écrit sur la sortie standard, rien n'est capturé par une substitution de commande.
- Oui, il peut lire à partir d'un tuyau. Il ne peut toujours pas écrire sur la sortie standard, et donc de ne pas générer du contenu que de la substitution de commande va lire.
- OK, comment puis-je rediriger la sortie vers std sortie?
- La rédaction de contenu dans des fichiers séparés pas plus grand qu'une taille maximale de chaque est le but que
split
existe. Avez-vous pensé que peut-être ce que vous voulez peut être un outil autre quesplit
, puisque ce n'est pas ce que vous essayez de faire? - Laissez-nous continuer cette discussion dans le chat.
Vous devez vous connecter pour publier un commentaire.
Puisque vous attendez des retours à la ligne, vous pouvez simplement remplacer toutes les instances de
mm
dans votre chaîne avec un saut de ligne. Dans le plus pur natif bash:Si vous vouliez faire un tel remplacement à plus de flux d'entrée, vous pourriez être mieux à l'aide de
awk
, que bash est intégré dans la manipulation de la chaîne n'a pas d'échelle bien plus que quelques kilo-octets de contenu. Legsub_literal
fonction shell (backending enawk
) donné dans BashFAQ #21 est applicable:...utilisé, dans ce contexte, comme:
Plus général de l'exemple, sans avoir à remplacer les caractères multi-séparateur avec un seul caractère délimiteur est donnée ci-dessous :
À l'aide du paramètre expansions : (à partir du commentaire de @gniourf_gniourf)
Plus brut de décoffrage de façon
De référence - Bash Tutoriel - Bash Scinde Une Chaîne
str="LearnABCtoABCSplitABCaABCString" delimiter=ABC s=$str$delimiter array=(); while [[ $s ]]; do array+=( "${s%%"$delimiter"*}" ); s=${s#*"$delimiter"}; done; declare -p array
. C'est tout.str="Nope:" delimiter="::"
s="a::b:" delimiter="::" array=(); while [[ $s ]]; do array+=( "${s%%"$delimiter"*}" ); c="${array[@]: -1}"; s="${s:${#c}}"; [[ $s != "$delimiter" ]] || { array+=(""); break; }; s="${s#"$delimiter"}"; done; declare -p array
L'outil recommandé pour le personnage de subtitution est
sed
's de commandes/regexp/replacement/
pour une regexp occurence ou mondials/regexp/replacement/g
, vous n'avez même pas besoin d'une boucle ou variables.Tuyau de votre
echo
de sortie et d'essayer de remplacer les caractèresmm
avec le caractère de saut de ligne\n
:echo "emmbbmmaaddsb" | sed 's/mm/\n/g'
La sortie est:
echo | sed
approche, bien que laconique, a beaucoup de frais généraux en termes de la façon dont il est mis en œuvre sous le capot-exigeant, en général, deux fourchettes, une mkfifo, unexecv
d'un outil externe qui doit être lié-et-chargé, etc).echo | sed
pour chaque ligne absolument être un antipattern. (L'appel desed
une fois pour traiter l'intégralité du flux entrant, en revanche, est souvent le cas).Avec awk vous pouvez utiliser le gsub pour remplacer toutes les correspondances regex.
Que dans votre question, à remplacer toutes les sous-chaînes de deux ou plus de deux 'm' caractères avec une nouvelle ligne, exécutez:
Le ‘g’ de gsub() est l'acronyme de “global”, ce qui signifie remplacer partout.
Vous pouvez également demander à imprimer N match, par exemple: