打印shell环境功能在一行上

时间:2017-03-29 18:31:06

标签: bash shell awk sed

在bash中,运行set将显示所有环境设置。我希望将每个函数的函数显示为一行。因此,而不是运行set并获得此(例如):

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
}

我想看到这个:

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 }

所以我想我想要一个sed / awk命令来查找正则表达式' ()$'并连接后面的每一行(用空格分隔字符),直到匹配正则表达式'^}$',其他任何东西都应该按原样打印。

更新:到目前为止提交的所有示例都会获取所有输入并将其渲染到一行,这并不完全正确。我希望每个函数(' ()$''^}$'的集合)都是一行。

3 个答案:

答案 0 :(得分:2)

脚本

试试这个:

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

可能会呈现:

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;}

我已经添加了半列以便能够获得输出。

更强

此版本将解析set命令的输出而不带参数,并使用所有,但仅函数:

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

这可以写成:

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

注意:[a-z0-9A-Z_.-]\+未经过充分验证:我不完全确定函数名称可能包含的内容。

详细说明

有一个可运行的脚本,其中包含逐行说明

#!/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
}

将其复制到您可以调用bashFuncToOneLine.sed然后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

答案 1 :(得分:1)

在awk中:

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

或删除file并向其发送管道(在这种情况下,您需要awk -v ORS=''...)。结果:

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}
  • }替换为}\n
  • 并使用ORS=''删除(除了上述)换行符
  • $1=$1重建记录以修剪空间

答案 2 :(得分:0)

试试这个 -

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 }