web-dev-qa-db-fra.com

Lignes de continuation Bash

Comment utilisez-vous les lignes de continuation de bash?

Je me rends compte que vous pouvez faire ceci:

echo "continuation \
lines"
>continuation lines

Cependant, si vous avez du code en retrait, cela ne fonctionne pas très bien:

    echo "continuation \
    lines"
>continuation     lines
122
user880248

C'est ce que vous voudrez peut-être

$       echo "continuation"\
>       "lines"
continuation lines

Si cela crée deux arguments pour faire écho et que vous n'en voulez qu'un, alors examinons la concaténation de chaînes. En bash, placez deux chaînes l'une à côté de l'autre pour concaténer:

$ echo "continuation""lines"
continuationlines

Ainsi, une ligne de continuation sans retrait est un moyen de rompre une chaîne:

$ echo "continuation"\
> "lines"
continuationlines

Mais lorsqu'un retrait est utilisé:

$       echo "continuation"\
>       "lines"
continuation lines

Vous obtenez deux arguments car il ne s'agit plus d'une concaténation.

Si vous souhaitez une seule chaîne qui traverse des lignes, tout en mettant en retrait mais sans obtenir tous ces espaces, vous pouvez essayer de supprimer la ligne de continuation et d'utiliser des variables:

$ a="continuation"
$ b="lines"
$ echo $a$b
continuationlines

Cela vous permettra d’avoir un code bien mis en retrait au détriment de variables supplémentaires. Si vous rendez les variables locales, cela ne devrait pas être trop grave.

132
Ray Toal

Ici, les documents avec le terminateur <<-HERE fonctionnent bien pour les chaînes de texte multilignes en retrait. Cela supprimera tous les onglets principaux du document ici. (Les terminateurs de ligne resteront toujours, cependant.)

cat <<-____HERE
    continuation
    lines
____HERE

Voir aussi http://ss64.com/bash/syntax-here.html

Si vous devez préserver certains espaces, mais pas tous, vous pouvez utiliser quelque chose comme:

sed 's/^  //' <<____HERE
    This has four leading spaces.
    Two of them will be removed by sed.
____HERE

Pour l’enveloppement de longues chaînes complexes sur plusieurs lignes, j’aime printf:

printf '%s' \
    "This will all be printed on a " \
    "single line (because the format string " \
    "doesn't specify any newline)"
24
tripleee

Vous pouvez utiliser bash arrays

$ str_array=("continuation"
             "lines")

puis

$ echo "${str_array[*]}"
continuation lines

il y a un espace supplémentaire, car (après le manuel bash):

Si le mot est cité entre guillemets, ${name[*]} devient un mot unique avec la valeur de chaque membre du tableau séparée par le premier caractère du Variable IFS

Donc, définissez IFS='' pour vous débarrasser de l'espace supplémentaire

$ IFS=''
$ echo "${str_array[*]}"
continuationlines
7
tworec

Je suis tombé sur une situation dans laquelle je devais envoyer un long message dans le cadre d'un argument de commande et que je devais respecter la limite de longueur de ligne. Les commandes ressemblent à ceci:

somecommand --message="I am a long message" args

La façon dont j'ai résolu ce problème est de déplacer le message comme un document ici (comme suggéré par @tripleee). Mais un document ici devient un stdin, il a donc besoin d'être relu, je suis allé avec l'approche ci-dessous:

message=$(
    tr "\n" " " <<- END
        This is a
        long message
END
)
somecommand --message="$message" args

Cela présente l'avantage que $message peut être utilisé exactement comme la constante de chaîne, sans espaces ni sauts de ligne supplémentaires.

Notez que les lignes de message réelles ci-dessus sont préfixées par un caractère tab chacune, qui est enlevé par le document here lui-même (en raison de l'utilisation de <<-). Il y a toujours des sauts de ligne à la fin, qui sont ensuite remplacés par dd par des espaces.

Notez également que si vous ne supprimez pas les nouvelles lignes, elles apparaîtront telles quelles lorsque "$message" est développé. Dans certains cas, vous pouvez résoudre ce problème en supprimant les guillemets autour de $message, mais le message ne sera plus un argument simple.

2
haridsv

Vous pouvez simplement le séparer avec des nouvelles lignes (sans utiliser de barre oblique inverse) comme requis dans l'indentation comme suit et simplement en lissant de nouvelles lignes.

Exemple:

echo "continuation
of 
lines" | tr '\n' ' '

Ou s'il s'agit d'une définition de variable, les nouvelles lignes sont automatiquement converties en espaces. Donc, bande d'espaces supplémentaires seulement si applicable.

x="continuation
of multiple
lines"
y="red|blue|
green|yellow"

echo $x # This will do as the converted space actually is meaningful
echo $y | tr -d ' ' # Stripping of space may be preferable in this case
1
rjni

En fonction du type de risque que vous accepterez et du degré de connaissance et de confiance accordé aux données, vous pouvez utiliser une interpolation de variable simpliste.

$: x="
    this
    is
       variably indented
    stuff
   "
$: echo "$x" # preserves the newlines and spacing

    this
    is
       variably indented
    stuff

$: echo $x # no quotes, stacks it "neatly" with minimal spacing
this is variably indented stuff
0
Paul Hodges

Cependant, si vous avez du code en retrait, cela ne fonctionne pas très bien:

    echo "continuation \
    lines"
>continuation     lines

Essayez avec des guillemets simples et en enchaînant les chaînes:

    echo 'continuation' \
    'lines'
>continuation lines

Remarque: la concaténation comprend un espace blanc.

0
mMontu

Ce n'est pas exactement ce que l'utilisateur a demandé, mais un autre moyen de créer une longue chaîne qui s'étend sur plusieurs lignes consiste à la construire progressivement, comme suit:

$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World

Évidemment, dans ce cas, il aurait été plus simple de le construire en une fois, mais ce style peut être très léger et compréhensible s’il s’agit de chaînes plus longues.

0
Jon McClung