私はよくこのようなプロジェクトディレクトリレイアウトを持っています
project
`-- component-a
| `-- files...
`-- component-b
| `-- files...
`-- component-c
`-- files...
私は通常、component
ディレクトリの1つで作業します。これは、そこにファイルがあるためです。その後、シェルに戻ると、特にすべてのコンポーネントにスクリプト化できない変更をいくつか加える必要がある場合は、兄弟ディレクトリに移動する必要があることがよくあります。そのような場合、前の兄弟ディレクトリが何であるか、または次の兄弟ディレクトリが何であるかは気にしません。
前のディレクトリまたは次のディレクトリ(アルファベットなど)に単にprev
するコマンドnext
またはcd
を定義できますか? cd ../com<TAB><Arrow keys>
と入力するのはいつも少し古くなっているからです。
他の答え からのcommandlinefuソリューションを使用しないでください:それは安全ではありません¹そして非効率的です。²代わりに、bash
を使用している場合は、次の関数を使用してください。それらを永続的にするには、それらを.bashrc
に入れます。組み込みで簡単なため、globorderを使用していることに注意してください。ただし、ほとんどのロケールでは、通常、グロブの順序はアルファベット順です。移動する次または前のディレクトリがない場合は、エラーメッセージが表示されます。特に、ルートディレクトリ/
でnext
またはprev
を実行しようとすると、エラーが表示されます。
## bash and zsh only!
# functions to cd to the next or previous sibling directory, in glob order
prev () {
# default to current directory if no previous
local prevdir="./"
local cwd=${PWD##*/}
if [[ -z $cwd ]]; then
# $PWD must be /
echo 'No previous directory.' >&2
return 1
fi
for x in ../*/; do
if [[ ${x#../} == ${cwd}/ ]]; then
# found cwd
if [[ $prevdir == ./ ]]; then
echo 'No previous directory.' >&2
return 1
fi
cd "$prevdir"
return
fi
if [[ -d $x ]]; then
prevdir=$x
fi
done
# Should never get here.
echo 'Directory not changed.' >&2
return 1
}
next () {
local foundcwd=
local cwd=${PWD##*/}
if [[ -z $cwd ]]; then
# $PWD must be /
echo 'No next directory.' >&2
return 1
fi
for x in ../*/; do
if [[ -n $foundcwd ]]; then
if [[ -d $x ]]; then
cd "$x"
return
fi
Elif [[ ${x#../} == ${cwd}/ ]]; then
foundcwd=1
fi
done
echo 'No next directory.' >&2
return 1
}
¹すべての可能なディレクトリ名を処理するわけではありません。 ls
出力の解析は決して安全ではありません 。
²cd
はおそらくそれほど効率的である必要はありませんが、6つのプロセスは少し過剰です。
次の関数は、兄弟ディレクトリへの変更を許可します(bash関数)
function sib() {
## sib search sibling directories
## Prompt for choice (when two or more directories are found, current dir is removed from choices)
## change to directory after selection
local substr=$1
local curdir=$(pwd)
local choices=$(find .. -maxdepth 1 -type d -name "*${substr}*" | grep -vE '^..$' | sed -e 's:../::' | grep -vE "^${curdir##*/}$" | sort)
if [ -z "$choices" ]; then
echo "Sibling directory not found!"
return
fi
local count=$(echo "$choices" | wc -l)
if [[ $count -eq 1 ]]; then
cd ../$choices
return
fi
select dir in $choices; do
if [ -n "$dir" ]; then
cd ../$dir
fi
break
done
}
使用例:
$ tree
.
├── component-aaa-01
├── component-aaa-02
├── component-bbb-01
├── component-bbb-02
├── component-ccc-01
├── component-ccc-02
└── component-ccc-03
7 directories, 0 files
$ cd component-aaa-01/
$ sib bbb-01
$ pwd
component-bbb-01
$ sib bbb
$ pwd
component-bbb-02
$ sib ccc
1) component-ccc-01
2) component-ccc-02
3) component-ccc-03
#? 3
$ pwd
component-ccc-03
$ sib 01
1) component-aaa-01
2) component-bbb-01
3) component-ccc-01
#? 2
$ pwd
component-bbb-01
commandlinefu.com でヒントを見つけました。見つけやすくするために、ここに再投稿します。説明とnext
コマンドを追加します。
alias prev='cd ../"$(ls -F .. | grep '/' | grep -B1 -xF "${PWD##*/}/" | head -n 1)"'
alias next='cd ../"$(ls -F .. | grep '/' | grep -A1 -xF "${PWD##*/}/" | tail -n 1)"'
魔法は `$(...)ブロックにあります。次のように、いくつかのコマンドを相互にパイプします。
ls -F .. | # list items in parent dir; `-F` requests filetype indicators
grep '/' | # select the directories (written as `mydir/`)
grep -B1 -xF "${PWD##*/}/" | # search for the name of the current directory in the output;
# print it and the line preceding it
head -n 1 # the first of those two lines contains the name of the previous sibling