Comment puis-je supprimer l'espace entre les arguments générés pendant l'expansion de l'accolade?

8

J'ai utilisé la commande suivante pour créer une liste d'URL que je veux tester:

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

Malheureusement, les URL ajoutées à urls.txtchacune avaient un espace devant elles (sauf la première, bien sûr). Je comprends pourquoi cela s'est produit, et je me rends compte que je pourrais simplement le retirer en passant par une sedexpression, mais j'aimerais savoir s'il existe un moyen de le supprimer à la place. (Cela peut sembler idiot et pédant, mais ce n'est pas différent de la préférence que tant de gens ressentent pour ne pas «abuser des chats» .)

J'ai essayé les guillemets doubles pour supprimer la séparation des mots , mais cela a également supprimé l'expansion de l'accolade, donc c'était un non-go.

J'ai essayé de changer IFS en une chaîne vide, mais cela n'a pas fonctionné non plus:

IFS='' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

Pas plus que de le changer en une nouvelle ligne:

IFS='\n' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt
iconoclaste
la source
Utilisez-vous bash ou zsh?
Braiam
en ce moment j'utilise bash (je suis au travail) mais sur mon propre ordinateur portable j'utilise zsh. Je m'attendais à ce que l'expansion de l'accolade fonctionne de manière identique dans les deux, mais ce n'est peut-être pas le cas.
iconoclaste du
Dans ce cas, la réponse de Gnouc sera la plus compatible avec différents coques.
Braiam
La réponse de Richard ne serait-elle pas également compatible? (Il a également l'avantage d'être plus simple, donc je n'ai pas à m'arrêter et à penser aux morceaux délicats la prochaine fois que je veux l'utiliser.) D'un autre côté, la réponse de Gnouc est également excellente. Et je pense que j'ai appris le plus de la réponse de glenn jackson. La réponse de Leiaz semble la plus simple et la plus élégante, mais bien sûr est uniquement zsh.
iconoclaste du

Réponses:

8

Vous pouvez stocker l'extension d'accolade dans un tableau, puis la générer à la manière de votre choix:

urls=( localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} )

alors

printf "%s\n" "${urls[@]}"

ou

(IFS=$'\n'; echo "${urls[*]}")

L'exemple d'écho est étrange car:

  1. il est exécuté dans un sous-shell (les parenthèses), donc je ne modifie pas ma valeur actuelle d'IFS.
  2. IFS doit être défini dans une commande distincte:
    • Cela ne fonctionne pas: IFS=$'\n' echo "${urls[*]}"parce que la variable est développée avant que la nouvelle variable env prenne effet
    • IFS doit être défini avant de commencer à développer des variables.

Notez également la différence subtile dans l'index de tableau de déréférencement utilisé:

  • [@] dans l'exemple printf pour étendre le tableau en mots individuels
  • [*] dans l'exemple d'écho pour développer le tableau en un seul mot, avec des éléments séparés par le premier caractère d'IFS
glenn jackman
la source
C'est un appel difficile, mais je choisis cette réponse parce que (1) elle semble (AFAIK) être la plus proche de l'objectif déclaré de supprimer plutôt que de simplement supprimer les espaces, et (2) j'en ai le plus appris (un objectif déclaré de ma question).
iconoclaste
16

Utilisez printfbuiltin:

$ printf %s\\n localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}
localhost:8080/reports/promos/130
localhost:8080/reports/promos/130.pdf
localhost:8080/reports/promos/130.xls
localhost:8080/reports/promos/130.xlsx
localhost:8080/reports/promos/130.csv
localhost:8080/reports/promos/130.preload
localhost:8080/reports/promos/130-unburdened
localhost:8080/reports/promos/130-unburdened.pdf
localhost:8080/reports/promos/130-unburdened.xls
localhost:8080/reports/promos/130-unburdened.xlsx
localhost:8080/reports/promos/130-unburdened.csv
localhost:8080/reports/promos/130-unburdened.preload
....
cuonglm
la source
6

C'est tagué zsh, donc je suggère le builtin zsh print:

print -l localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}

-l imprime les arguments sur des lignes distinctes.

Leiaz
la source
+1 Merci - bon à savoir! Je l'utiliserai quand je serai sur zsh. Je l'ai marqué simplement parce que j'utilise les deux et que les deux prennent en charge l'expansion des accolades. (Je ne sais pas si d'autres le font, mais je trouve ksh terriblement déroutant, alors je reste à l'écart.)
iconoclaste
3

Le problème est que l'extension d'accolade ajoute de l'espace, et l'écho ajoute la nouvelle ligne. Donc, en utilisant le principe de responsabilité unique, gérez la nouvelle ligne séparément.

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} | tr " " "\n"
ctrl-alt-delor
la source
Je pense que c'est l'approche la plus simple et la plus pratique
iconoclaste
Non, l'expansion d'accolade n'ajoute pas d'espace, elle crée plusieurs arguments echo. C'est echocela qui imprime ses arguments séparés par des espaces.
Stéphane Chazelas
Je suppose que le problème se produit parce que les echoarguments sont séparés par des espaces et la nouvelle ligne est insérée en plus avant chaque espace au lieu de remplacer l'espace (ce qui serait plus judicieux). De mémoire, xargsa un problème connu très similaire à celui-ci (en particulier avec l' -0option)
erreur de syntaxe