首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash提速缩短

Bash提速缩短
EN

Stack Overflow用户
提问于 2016-05-27 22:52:31
回答 2查看 1K关注 0票数 5

我刚从tcsh转到bash,特别是错过了使用%c02缩短提示选项的目录( ellipsis也设置了)。

我看到PROMPT_DIRTRIM做了几乎正确的事情(除了省略号,我认为),但我只在bash 3上(在OS上)。我找到了其他地方的菜谱,它缩短了总长度,所以在目录中间断开路径名,这是我不喜欢的。

所以我想出了这个:

代码语言:javascript
复制
PROMPT_DIRTRIM=2   ## from bash4, but used here
dirtrim() 
{
    local NAME="$1" start= endelts=
    [[ "$NAME" =~ ^"$HOME"(/|$) ]] && NAME="~${NAME#$HOME}"  ## $HOME ==> ~
    IFS=/ read -ra elts <<< "$NAME";          ## split $PWD on "/"
    start=$((${#elts[@]}-${PROMPT_DIRTRIM}))  ## first element to retain
    if [ ${start} -gt 1 ]; then     
        for ((i=${start}; i<${#elts[@]}; i++)); do 
            endelts="${endelts}/${elts[$i]}"; ## concat together the trailing path
        done
        NAME="...${endelts}"
    fi
    echo "$NAME"    
}
PS1='\h:$(dirtrim "$PWD")\$ '

它的作用是:

代码语言:javascript
复制
blackat:~$ cd ~/Library/Application\ Support/Apple
blackat:.../Application Support/Apple$

但是我对bash很陌生,对显式的for (())循环不满意;但是,我似乎找不到任何其他方法来重新加入拆分elts数组的最后一个条目,以正确处理dir名称中的空格(例如,使用${elts[@]:${start}})。有什么提示可以这样做或其他改进吗?

(顺便说一句,我认为这是一个编程问题,在某种程度上bash是一种编程语言.)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-27 23:45:57

你可以试试这个:

代码语言:javascript
复制
if ((start > 1)); then
  name=$(IFS=/; echo .../"${elts[*]:start}")
  # If your terminal is correctly set up for unicode, you can save two character positions:
  # name=$(IFS=/; echo …/"${elts[*]:start}")
fi

注意,在bash中,在算术上下文(包括((...))和数组下标的内部)中,您可以只编写变量的名称;不需要sigils。

另一种方法是

代码语言:javascript
复制
if ((start > 1)); then
  printf -v name "/%s" "${elts[@]:start}"
  name=...$name
fi

另一种解决方案是在BASH_REMATCH数组中使用regex捕获,而不是拆分和重新连接字符串:

代码语言:javascript
复制
dirtrim () { 
  local path="$1";
  [[ $path =~ ^"$HOME"(/.*)? ]] && path=~${BASH_REMATCH[1]};
  ((PROMPT_DIRTRIM)) &&
    [[ $path =~ ...*((/[^/]*){$PROMPT_DIRTRIM}) ]] &&
    path=…${BASH_REMATCH[1]};
  echo "$path"
}

由于bash计算在算术上下文中的特性,((PROMPT_DIRTRIM))测试并不完全健壮。对于发行版,您可能更喜欢类似于[[ $PROMPT_DIRTRIM =~ ^[1-9][0-9]*$ ]]的内容

票数 3
EN

Stack Overflow用户

发布于 2016-05-27 23:46:41

这并不是一个真正的答案,但您可能想看看mksh是如何做到这一点的:

代码语言:javascript
复制
PS1=${| local e=$? (( e )) && REPLY+="$e|" REPLY+=${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \?)} REPLY+=@${HOSTNAME%%.*}: local d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || d=${d/#$p/~} local m=${%d} n p=...; (( m > 0 )) || m=${#d} (( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || p= REPLY+=$p$d return $e }

不幸的是,我相信它使用了一些不在bash中的扩展。

麻生太郎既然你换壳了..。你有没有考虑过

它是从盒子里拿出来的,然后还有一些。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37493371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档