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

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

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
....

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.


+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"

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.