より良いもの

より良いもの

function私のファイルにコピーがあります.bashrc。私はそれが何をしているのか知っています。 Xディレクトリを追加します。cd

ここにいる:

up()
{
    local d=""
    limit=$1
    for ((i=1 ; i <= limit ; i++))
      do
        d=$d/..
      done
    d=$(echo $d | sed 's/^\///')
    if [ -z "$d" ]; then
      d=..
    fi
    cd $d
}

しかし、これら3つを私に説明してもらえますか?

  1. d=$d/..
  2. sed 's/^\///'
  3. d=..

これをしてはいけない理由:

up()
{
    limit=$1

    for ((i=1 ; i <= limit ; i++))
    do
        cd ..
    done
}

使用法:

<<<>>>~$ up 3
<<<>>>/$

答え1

  1. d=$d/../..変数に追加された現在の内容dd何もせずに開始し、最初の反復が成功し、/..2回目の反復/../..などが続きます。

  2. sed 's/^\///'最初のものを削除して/ください/../..(  ../..パラメータ拡張を使用して実行できますd=${d#/})。

  3. d=..その条件の文脈でのみ意味があります。

    if [ -z "$d" ]; then
      d=..
    fi
    

    これにより、dこの時点で空の場合は親ディレクトリにリダイレクトされます。 (upパラメータのないものと同じですcd ..。)

このアプローチは、ある段階で(ユーザーの観点から)以前のディレクトリに戻ることができる機能を維持するため、繰り返しcd ..よりも優れています。cd -

この機能は次のように単純化できます。

up() {
  local d=..
  for ((i = 1; i < ${1:-1}; i++)); do d=$d/..; done
  cd $d
}

これは、少なくとも1つのレベルを上回って追加したいと仮定します。n-1/レベルなので、先行を削除したり空であることを確認する必要はありません$d

Athenaを使うjotathena-jotDebianのパッケージ):

up() { cd $(jot -b .. -s / "${1:-1}"); }

(目安として変形次の提案グレンジャックマン)。

答え2

しかし、これら3つを私に説明してもらえますか?

  1. d=$d/..

    これはvarの現在の内容をdvarに関連付け/..て再割り当てしますd
    最終結果d/../../../..

  2. sed's/^///'

    公開したコードに指定された/文字列から先行(echo $ d)を削除します。バックスラッシュを避けるために書く方が良いかもしれません。 d
    sed 's|^/||'

    別のオプション(より速くて簡単)はd=${d#/}

  3. ディ=..

    ..varに文字列を割り当てますd
    これはd少なくとも一つ ..テスト結果if [ -z "$d" ]; thenvardが空であるとマークされている場合。これは、sedコマンドが文字を削除するために発生する可能性がありますd
    dから文字を削除する必要がない場合、sedまたはこれは不要ですif


質問のコードは常に1つ以上のディレクトリの上に移動します。

より良いもの

  • local d変数が空であることを確認するだけで十分であり、他のものは必要ありません。
    しかし、localはbashやdashなどの特定のシェルでのみ機能します。具体的には、ksh(as yash)にコマンドはありませんlocal。より移植性に優れたソリューションは次のとおりです。

    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
    
  • 構文はfor((移植可能ではありません。次のようなものを使用することをお勧めします。

    while [ "$((i+=1))" -lt "$limit" ]; do
    
  • 強い。
    関数の最初の引数に指定された値が負またはリテラルである場合、関数はこれらの値を強力に処理できる必要があります。
    まず、値を数値に制限します。 (私はcに使用しますcount):

    c=${1%%[!0-9]*}
    

    次に、数値を正の値に限定します。

    let "c = (c>0)?c:0"
    

この関数はゼロまたはすべてのテキスト(エラーなし)を受け入れます。

up()
{
    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
    c=${1%%[!0-9]*}
    c=$(((c>0)?c:0))
    while [ "$((i+=1))" -le "$c" ]; do d="$d../"; done
    echo \
        cd "${d%/}"         # Removing the trailing / is not really needed for cd
                            # but it is nice to know it could be done cleanly.
}

up 2
up 0
up asdf

echo \機能をテストしたら、削除してください。

関連情報