Comment éviter bash de la substitution de commande pour supprimer le caractère de saut de ligne?
Pour accélérer un script bash exécution, je tiens à garder le résultat d'une commande dans une variable à l'aide de la substitution de commande, mais la substitution de commande remplace le 0x0A
caractère de saut de ligne par un espace. Par exemple:
a=`df -H`
ou
a=$( df -H )
Quand je veux processus de $a
, les caractères de saut de ligne sont remplacés par un espace et toutes les lignes sont maintenant sur une seule ligne, ce qui est beaucoup plus difficile de grep:
echo $a
Quels seraient les conseils pour éviter le caractère de saut de ligne supprimée par la substitution de commande?
Vous devez vous connecter pour publier un commentaire.
Non de fuite des retours à la ligne ne sont pas supprimés
Les retours à la ligne que vous cherchez sont là, vous ne les voyez pas, parce que vous utilisez
echo
sans citer de la variable.Validation:
De fuite retours à la ligne sont supprimés
Comme @user4815162342 souligné à juste titre, bien que les retours à la ligne dans la sortie ne sont pas supprimés, de fuite des retours à la ligne sont enlevés avec une substitution de commande. Voir l'expérience ci-dessous:
Dans la plupart des cas, cela n'a pas d'importance, parce que
echo
va ajouter de la disparition de retour à la ligne (sauf si elle est invoquée avec la-n
option), mais il y a certains cas où il y a plus qu'une fuite des retours à la ligne dans la sortie d'un programme, et ils sont importants pour une raison quelconque.Solutions de contournement
1. Ajouter mannequin de caractère
Dans ces cas, comme @Scrutinizer mentionné, vous pouvez utiliser la solution de contournement suivante:
Explication: Caractère
x
est ajouté à la sortie (à l'aide deprintf x
), après les retours à la ligne. Depuis les retours à la ligne ne sont pas de fuite plus, ils ne sont pas supprimés par la substitution de commande. La prochaine étape consiste à supprimer lex
nous avons ajouté, à l'aide de la%
opérateur dans${a%x}
. Maintenant, nous avons la sortie d'origine, avec tous les retours à la ligne actuelle!!!2. Lecture à l'aide de processus de substitution
Au lieu d'utiliser la substitution de commande affecter la sortie d'un programme de variable, on peut, au lieu d'utiliser processus de substitution pour nourrir la sortie du programme de la
read
de commande intégrée (crédit à @ormaaj). Processus de substitution conserve tous les retours à la ligne. La lecture de la sortie d'une variable est un peu difficile, mais vous pouvez le faire comme ceci:Explication:
IFS=
. Sinonread
ne serait pas affecter l'ensemble de la sortie devar
, mais seulement le premier jeton.lire
avec des options-rd ''
. Ler
est pour la prévention de la barre oblique inverse à agir comme un caractère spécial, et avecd ''
définir le séparateur à rien, de sorte que lire lit l'intégralité de sortie, au lieu de simplement la première ligne.3. Lire à partir d'un tuyau
Au lieu de l'aide de la commande ou le processus de substitution d'affecter la sortie d'un programme de variable, on peut, au lieu de rediriger la sortie du programme pour le
read
de commande (crédit à @ormaaj). Tuyauterie conserve également tous les retours à la ligne. À noter toutefois, que cette fois nous avons mis l'lastpipe
shell comportement en option, à l'aide de leshopt
builtin. Cela est nécessaire, de sorte que leread
commande est exécutée dans le courant de l'environnement de shell. Sinon, la variable sera affecté dans un shell interne est exécuté, et il ne sera pas accessible depuis le reste du script.a=$(printf 'test\n\n'; printf x); echo "${a%x}"
read
non standard des options pour effectuer la cession.shopt -s lastpipe; printf %s "$myData" | IFS= read -rd '' var
. Bash estprintf -v
est également utile dans certaines situations semblables.read
, mais il ne s'applique pas à Bash.)(
)
de travailler dans le terminal comme ceci:( shopt -s lastpipe; printf 'test\n\n' | IFS= read -rd '' var; echo "$var"; )
lastpipe
(bien que j'ai l'habitude d'utiliserlastpipe
de toute façon). La raison pour laquelle vous avis, c'est en raison de l'emploi de contrôle. Shell interactif ontset -m
laquelle les forces de pipelines pour s'exécuter en séparer les groupes de processus, ce qui nécessite un sous-shell pour le dernier élément. Depuis le contrôle du travail ne s'applique pas aux enfants de un shell interne est exécuté, l'emballage tout en(...)
est une solution de contournement (que j'ai presque toujours lors de l'essai de manière interactive, de toute façon).read
sorties avec non nul, quand il frappe les expressions du FOLKLORE. Cela provoque les méthodes 2 et 3 de sortie non nul, par conséquent, de masquage de commande principale de l'état de sortie. Dans la Méthode 1 en utilisantmain_cmd ; printf x
remplace également le principal commandes code de sortie et interfère avec la gestion des erreurs. Essayezmain_cmd && printf x
à la place (si les lignes de fuite sont importantes uniquement sur la réussite de sortie) oumain_cmd ; ec=$?; printf x; exit $ec
pour garder des espaces à la fois les succès et les cas d'erreur.read
méthode. Elle masque le statut de sortie. Lire le commentaire ci-dessus.PIPESTATUS
tableau. Cela ne fonctionne que si vous utilisez un pipeline, que bash ne pas exposer l'état de sortie des processus de substitution.shopt -s lastpipe; { printf %s $'foo\nbar'; exit 3; } | IFS= read -rd '' x; printf '%q, %s\n' "$x" "${PIPESTATUS[0]}"
J'ai été d'essayer d'envelopper ma tête autour de cela parce que j'ai été en utilisant bash de flux dans le résultat de l'exécution de l'interprète sur un F# script. Après quelques essais et erreurs, ce qui s'est avéré pour résoudre le problème:
En supposant, bien sûr, que vous devez exécuter un programme de terminal.
Espérons que cette aide.