2 votes

Imprimer les fonctions de l'environnement shell sur une seule ligne

En bash, il suffit d'exécuter set affichera tous les paramètres de l'environnement. Je souhaite afficher mes fonctions sur une seule ligne pour chacune d'entre elles. Ainsi, au lieu d'exécuter set et d'obtenir ceci (par exemple) :

gcm ()
{
    git commit -m "$@";
    git --no-pager log -1 | grep --color ^commit
}
gcma ()
{
    git commit -a -m "$@";
    git --no-pager log -1 | grep --color ^commit
}

Je veux voir ça :

gcm () { git commit -m "$@"; git --no-pager log -1 | grep --color ^commit }
gcma () { git commit -a -m "$@"; git --no-pager log -1 | grep --color ^commit }

Je pense donc qu'il me faut une commande sed/awk qui recherchera les expressions rationnelles suivantes ' ()$' et concaténer toutes les lignes suivantes (avec un caractère de séparation) jusqu'à la regex '^}$' et tout le reste devrait s'imprimer tel quel.

MISE À JOUR : Tous les exemples présentés jusqu'à présent prennent toutes les entrées et les rendent sur une seule ligne, ce qui n'est pas tout à fait correct. Je veux que chaque fonction (l'ensemble des ' ()$' a '^}$' inclusivement) en une seule ligne.

2voto

F. Hauri Points 5893

Petit sédimentaire script

Essayez ceci :

declare -f gcm gcma dequote quote |
    sed '1h;1!H;/^}$/!d;s/.//;x;s/\n[ \o11]*//g;s/}$/;}/'

peut rendre :

gcm () { git commit -m "$@";git --no-pager log -1 | grep --color ^commit;}
gcma () { git commit -a -m "$@";git --no-pager log -1 | grep --color ^commit;}
quote () { local quoted=${1//\'/\'\\\'\'};printf "'%s'" "$quoted";}
dequote () { eval printf %s "$1" 2> /dev/null;}

J'ai ajouté une demi-colonne afin de pouvoir sourcer la sortie.

Plus fort

Cette version analysera la sortie de set sans argument et prend la commande tous, mais seulement fonctions :

set | sed '/^[a-z0-9A-Z_.-]\+ () *$/,/^}$/{ //{ /()/{h;d;}};H ;/^}$/!d;g;s/\n[ \o11]*//g;s/}$/;}/;p;};d'

Cela pourrait être écrit :

set | sed '
    /^[a-z0-9A-Z_.-]\+ () *$/,/^}$/{
      //{
        /()/ {
            h;
            d;
          };
      };
      H;
      /^}$/!d;
      g;
      s/\n[ \o11]*//g;
      s/}$/;}/;
      p;
    };
    d;
'

Remarque : [a-z0-9A-Z_.-]\+ n'est pas bien validée : Je ne suis pas tout à fait sûr de ce qu'un nom de fonction peut contenir.

Explication détaillée

Il existe un système exécutable sédimentaire script avec explication ligne par ligne

#!/bin/sed -nf
# -n modifier won't output anything without explicit 'p' command

/^[a-z0-9A-Z_.-]\+ () *$/ , /^}$/ { # from lines beginning by funcname, to ^}$
    //{                # At first or last line of block...
        /()/{          # If containing '()', 
            h;         # place this line in hold space,
            d;         # then delete (go to next line)
        };
    };
    H;                 # Append to hold space
    /^}$/!d;           # If not '^}$', delete this line (go to next line)
    g;                 # replace current line by hold space
    s/\n[ \o11]*//g;   # Suppress each new line and following spaces or tabs
    s/}$/;}/;          # Add semi-colon before last '}' in order to source
    p;                 # print
}

Copiez ceci dans un fichier que vous pouvez appeler bashFuncToOneLine.sed puis chmod +x spacebashFuncToOneLine.sed

declare -f gcm{,a}  | ./bashFuncToOneLine.sed 
gcm () { git commit -m "$@";git --no-pager log -1 | grep --color ^commit;}
gcma () { git commit -a -m "$@";git --no-pager log -1 | grep --color ^commit;}

set | ./bashFuncToOneLine.sed | less -S

1voto

James Brown Points 17362

En awk :

$ awk 'sub(/}/,"}\n")||$1=$1' ORS='' file

ou supprimer file et d'y raccorder un tuyau (dans ce cas, vous devez awk -v ORS=''... ). Résultat :

gcm (){git commit -m "$@";git --no-pager log -1 | grep --color ^commit}
gcma (){git commit -a -m "$@";git --no-pager log -1 | grep --color ^commit}
  • remplacer } con }\n
  • et utiliser ORS='' pour supprimer les nouvelles lignes (autres que celles ci-dessus)
  • et $1=$1 pour reconstruire les enregistrements afin de réduire l'espace

0voto

VIPIN KUMAR Points 2061

Essayez ceci -

awk  '{gsub(/[[:space:]]+/," ") ;ORS=(/}/?RS:FS)}1' f
gcm () {  git commit -m "$@";  git --no-pager log -1 | grep --color ^commit }
gcma () {  git commit -a -m "$@";  git --no-pager log -1 | grep --color ^commit }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X