Est-il possible de supprimer une chaîne spécifique avec la commande tr
dans un shell UNIX? Par exemple: si je tape:
tr -d "1."
et l'entrée est 1.1231
, cela montrerait 23
en sortie, mais je veux qu'il affiche 1231
(remarquez seulement le premier 1
est parti). Comment ferais-je ça?
Si vous connaissez une solution ou une meilleure façon, veuillez expliquer la syntaxe car je ne veux pas simplement copier-coller mais aussi apprendre.
J'ai d'énormes problèmes avec awk, donc si vous l'utilisez, expliquez-le encore plus.
Dans votre exemple ci-dessus, la commande cut suffirait.
Exemple: echo '1.1231' | cut -d '.' -f 2
retournerais 1231
.
Pour plus d'informations sur cut, tapez simplement man cut
.
Vous feriez mieux d'utiliser une sorte de regex (peut-être quelque chose comme sed).
Par exemple, avec l'entrée 1.1231, vous pouvez utiliser ce qui suit pour obtenir la sortie 1231:
sed 's/1\.//g'
Jetez un œil ici: http://tldp.org/LDP/abs/html/string-manipulation.html
Vous pouvez également utiliser sed pour ce genre de chose:
$ echo "1.1231" | sed -e "s/1\.//"
1231
Il s'agit simplement d'utiliser sed pour exécuter une recherche et un remplacement d'expressions régulières, en remplaçant "1". (avec échappement approprié) avec "". Il supprime uniquement la première correspondance par défaut.
Si vous utilisez bash
, vous pouvez le faire facilement avec substitution de paramètres :
$ a=1.1231
$ echo ${a#1.}
1231
Cela supprimera le début "1."
chaîne. Si vous souhaitez supprimer jusqu'à la première occurrence de , y compris, utilisez ${a#*1.}
et si vous souhaitez tout supprimer jusqu'à la dernière occurrence de , y compris, utilisez ${##*1.}
.
La page TLDP sur manipulation de chaîne a d'autres options (telles que l'extraction de sous-chaîne).
Notez que l'utilisation des outils de manipulation de chaîne intégrés standard sh
pour de telles transformations simples sera toujours beaucoup plus rapide que l'utilisation d'un outil externe, tel que sed
, awk
ou cut
car le Shell n'a pas à créer de sous-processus pour effectuer l'opération. Cependant, pour des choses plus compliquées (par exemple, vous devez utiliser des expressions régulières ou lorsque l'entrée est grande), vous êtes préférable d'utiliser les outils dédiés.
Puisque vous avez posé une question spécifique sur awk
, en voici une autre.
awk '{ gsub(/1\./,"") }1' input.txt
Comme tout tutoriel awk
vous le dira, la forme générale d'un programme awk
est une séquence de 'condition {actions}'. Si vous n'avez aucune action, l'action par défaut consiste à imprimer. Si vous n'avez aucune condition, les actions seront prises sans condition. Ce programme utilise ces deux cas particuliers.
La première partie est une action sans condition, c'est-à-dire qu'elle sera effectuée pour toutes les lignes. L'action consiste à remplacer toutes les occurrences de l'expression régulière /1\./
avec rien. Donc, cela coupera tout "1". (quel que soit le contexte) à partir d'une ligne.
La deuxième partie est une condition sans action, c'est-à-dire qu'elle s'imprimera si la condition est vraie et la condition est toujours vraie. C'est un idiome commun pour "nous avons terminé - imprimez tout ce que nous avons maintenant". Il se compose simplement de la constante 1
(qui, lorsqu'elle est utilisée comme condition, signifie "vrai", simplement).
Cela pourrait être reformulé de plusieurs façons. Par exemple, vous pouvez prendre en compte l'impression dans la première action;
awk '{ gsub(/1\./,""); print }' input.txt
Vous souhaitez peut-être remplacer la partie entière, c'est-à-dire tout nombre avant un signe de période. Le regex pour cela serait quelque chose comme /[0-9]+\./
.
gsub
est une extension GNU, vous pouvez donc la remplacer par sub
ou une sorte de boucle si vous avez besoin de portabilité vers l'héritage awk
syntaxe.