Đối với tôi Pushd / popd / dirs gần như hữu ích, nhưng thiếu. Vì vậy, tôi đã tạo ra một 'trình bao bọc' xung quanh những cái được gọi là 'navd', được triển khai thực chất như một bộ gồm 20 bí danh. (Một trong số đó là một chức năng, thực sự.) Đoạn mã dưới đây, nhưng đây là một lời giải thích ngắn gọn đầu tiên. (Một điều thú vị về "navd" và làm việc trên máy của người khác: Có một hình thức chạy "không cài đặt": Như một tùy chọn cài đặt, bạn có thể chỉ cần dán vào các lệnh thực hiện "navd" tại bash-prompt và trong khoảng thời gian của phiên bash cho máy điều hướng đó sẽ hoạt động. Điều đó cho phép in chân trong hệ thống tệp, nhưng nó chỉ là một bản cài đặt tạm thời. Đặt các lệnh đó vào .bashrc để cài đặt "thực", của khóa học.)
Tính năng, đặc điểm:
navd <path>; -- will make that path the current dir AND will add it to the stack
AS A BONUS: If a relative path is used, this command is added to history
with an absolute path instead. This improves navigation even when only
using history ... because very often relative-path commands in history
are useless if the command changes the current directory. (After all, you
would have to be in the directory the command was originally issued
from in order for such a command to work correctly.)
navd -- shows the stack, with index numbers for convenience
navd0 -- makes the first entry on the stack (read left-to-right) **the current dir**
navd1 -- makes the second entry on the stack (read left-to-right) **the current dir**
.
.
.
navd9 -- makes the tenth entry on the stack (read left-to-right) **the current dir**
navd-1 -- makes the first entry on the stack WHEN READ RIGHT-to-LEFT(!) **the current dir**
. ^^^^^^^^^^^^^^^^^^^^^^^^^^
.
.
navd-9 -- makes the 9th entry on the stack WHEN READ RIGHT-to-LEFT(!) **the current dir**
Bất kỳ lệnh nào trong số mười chín lệnh <N> điều hướng xoay ngăn xếp sao cho thư mục trở thành thư mục hiện tại cũng sẽ hiển thị ở phía trước ngăn xếp. Các giá trị <N> dương tìm thấy một thư mục đếm từ bên trái, với việc lập chỉ mục bắt đầu từ 0. Các giá trị <N> âm tìm thấy một thư mục đếm từ RIGHT, với việc lập chỉ mục bắt đầu từ -1. (Điều này tuân theo quy ước về cách các chỉ mục mảng có thể được sử dụng trong Java và các ngôn ngữ khác.)
Lưu ý: Bất kỳ lệnh "navd" nào cũng hiển thị cùng ngăn xếp mà "Pushd" và "dirs" sử dụng - nhưng hiển thị nó KHÔNG CÓ
mục nhập bên trái nhất mà "dirs" sẽ hiển thị (vì mục đó không thực sự nằm trên ngăn xếp - đó là thư mục hiện tại
và với "dirs" bên trái hầu hết các mục thay đổi nếu một lệnh cd được nhập). (The "cd <path>" lệnh không ảnh hưởng đến bất kỳ hành vi của navd dù nó chắc chắn không ảnh hưởng đến hành vi của pushd / dirs / popd Ngoài ra ... Tôi thích sử dụng. "Cd -" để đi "trở lại" một lần để một thư mục tôi vừa điều hướng khỏi và "cd -" cũng không ảnh hưởng đến hành vi của navd.)
Phần thưởng: Có thể có thêm 19 bí danh KHÔNG xoay vòng ngăn xếp, mà chỉ thay đổi thư mục đến vị trí được chỉ định trên ngăn xếp.
nav0 ... nav9 and nav-1 ... nav-9
Phần thưởng thứ 2: "navh" hiển thị các lệnh <path> navd từ lịch sử, để dễ dàng tải lên ngăn xếp với cut-n-paste. (Mỗi mục chỉ được liệt kê một lần ngay cả khi nó trong lịch sử nhiều lần và danh sách được sắp xếp. Ngoài ra, các mục có thể được đặt trong tệp $ HOME / .navhignore để ngăn những mục chính xác đó xuất hiện trong danh sách điều hướng.)
navh
Ba hành vi chính:
Nếu bạn xóa ngăn xếp và lặp lại lệnh "navd <path>" cụ thể, đường dẫn đó sẽ đi vào ngăn xếp. Đó là những gì tôi muốn và mong đợi ... nhưng Pushd không làm điều đó - nó đặt thư mục hiện tại bạn đang điều hướng TUYỆT VỜI trên ngăn xếp - vì vậy hiệu ứng trên ngăn xếp có thể thay đổi (cảm thấy không thể đoán trước) khi bạn lặp lại lệnh .
"navd <path>" sẽ không đặt cùng một đường dẫn trên ngăn xếp hai lần.
"navd <path>" đặt chính nó vào lịch sử lệnh với đường dẫn tuyệt đối ngay cả khi đường dẫn tương đối được nhập vào cho lệnh.
Đối với tôi, ba hành vi cuối cùng được mô tả làm cho việc sử dụng lệnh "navd <path>" từ lịch sử hữu ích hơn nhiều so với sử dụng "đẩy <path>" từ lịch sử. Tôi thực sự có thể sử dụng lại lịch sử để đi đến những nơi. Và khi tôi làm như vậy tôi không "làm hỏng" ngăn xếp của mình.
Nếu bạn có thể và muốn bọc bộ não của bạn xung quanh nó, bạn có thể chuyển đổi giữa việc sử dụng navd và Pushd / dirs / popd. Cả hai sử dụng cùng một ngăn xếp; chỉ với một phong cách khác nhau. Ví dụ: sử dụng "popd" để xóa mọi thứ khỏi ngăn xếp "navd" hoặc sử dụng "dirs -c" để xóa ngăn xếp navd.
Hãy nghĩ về Pushd / dirs / popd là "làm thế nào để tôi lấy lại các bước của mình?".
Hãy nghĩ về navd như "làm thế nào để tôi giữ một tập hợp các thư mục yêu thích và dễ dàng chuyển đổi giữa chúng?".
Dán đoạn sau vào cửa sổ terminal và bạn có thể bắt đầu sử dụng navd trong suốt thời gian của phiên cuối đó. Đây là tất cả các mã có tính năng này.
# Add 1 function and many related aliases for something like "pushd", called "navd". http://unix.stackexchange.com/a/229161
# Think of pushd/dirs/popd as "how do I retrace my steps?".
# Think of navd as "how do I hold on to a set of favorite directories, and easily switch between them?".
# Pseudo-code to explain each part of the "navd" bash function just below:
# If no arguments to the 'navd' command:
# If stack has entries, then print the stack one-line-per-dir with each line numbered.
# Else, if stack is empty, automatically run the equivalent of the navh command.
# Else (there **are** arguments to the 'navd' command):
# If arg is '--help' or '/?' then show help.
# Else (arg is assumed to be a path to a directory)
# Remember the directory we are starting at
# Change to dir given as argument (the "arg-dir"), and do a few chores:
# Do not use arg-dir literally ... instead, magically put the **absolute** path we arrived at into history.
# Set a flag if the arg-dir is already in the stack.
# If the flag is set then just show the stack (on one line), else ADD to stack, ROTATE to end-of-stack, and show the stack.
# Change to dir we started at and then back to the arg-dir. This allows "cd -" to go back to dir we started at.
# End-If
# End-If
navd () {
if [[ $1 == '' ]]; then #--no arguments to the 'navd' command
if dirs +1 >/dev/null 2>&1; then #------stack has entries
dirs -p | perl -ne 'print (-1+$cn++); print "$_"' | grep -v "^-1";
else #------stack is empty
echo "The navd stack is empty. Now running 'navh' in case that's helpful. navd --help works."
if [[ ! -f $HOME/.navhignore ]]; then echo -n ''>>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/ /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "`grep -c . <(sort -u $HOME/.navhignore)`" unique lines.)"
fi
else #--(there **are** arguments to the 'navd' command)
if [[ $1 == '--help' || $1 == '/?' ]]; then #------arg is '--help' or '/?'
echo "The 'navd' functionality is nothing but one bash function and a set of aliases."
echo "It offers a different style of handy directory navigation than pushd/popd."
echo "It uses the same 'stack' as pushd. Look in the .bashrc file for details."
echo " (Think of pushd/dirs/popd as 'how do I retrace my steps?'."
echo " Think of navd as 'how do I remember a set of favorite directories,"
echo " and easily switch between them?'.)"
echo "As of 10/2015, this link has more info: http://unix.stackexchange.com/a/229161"
echo "Here is the set of navd-related aliases. None need any parameter:"
alias | grep 'alias nav' | cut -d= -f1 | grep -v '-' | grep -v 'navh'
alias | grep 'alias nav' | cut -d= -f1 | grep '-'
echo "alias navh # The 'navh' alias has nothing to display until a 'navd <path>' is run. Short for nav-history."
echo "---- To get started, simpy type navd followed by your favorite path. ----"
echo "---- navd with no param shows stack. nav0 navigates to first on stack. ----"
else #------(arg is assumed to be a path to a directory)
mypwd="$PWD"
cd "$1" >/dev/null;
history -s `echo "$PWD" | perl -pe 's/$ENV{'HOME'}/~/;s/ /\\\\ /g;s/^/navd /'`
myflag=`dirs -p | perl -pe 's/\n/:/' | perl -ne '@a=split(":");$pwd=shift(@a);$flag=0;foreach (@a) {if ($_ eq $pwd) {$flag=1}};print $flag'`
if [[ $myflag == 1 ]]; then dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"; else pushd .>/dev/null; pushd +1>/dev/null; dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"; fi
cd "$mypwd"; cd "`dirs -l -0`"
fi
fi
};
# Aliases for navigating and rotating the "pushd" stack in the style of "navd":
alias navd0='cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"' # "-l" is dash-L, and expands "~" to denote the home dir. Needed inside back-ticks.
alias navd1='cd "`dirs -l +1`";pushd -n +1;cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd2='myd=$PWD;cd "`dirs -l +1`";for i in {1..2};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd3='myd=$PWD;cd "`dirs -l +1`";for i in {1..3};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd4='myd=$PWD;cd "`dirs -l +1`";for i in {1..4};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd5='myd=$PWD;cd "`dirs -l +1`";for i in {1..5};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd6='myd=$PWD;cd "`dirs -l +1`";for i in {1..6};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd7='myd=$PWD;cd "`dirs -l +1`";for i in {1..7};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd8='myd=$PWD;cd "`dirs -l +1`";for i in {1..8};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd9='myd=$PWD;cd "`dirs -l +1`";for i in {1..9};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-1='cd "`dirs -l -0`";pushd -n -0>/dev/null; dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-2='myd=$PWD;cd "`dirs -l -0`";pushd -n -0>/dev/null;cd "`dirs -l -0`";pushd -n -0>/dev/null;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-3='myd=$PWD;cd "`dirs -l -0`";for i in {1..3};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-4='myd=$PWD;cd "`dirs -l -0`";for i in {1..4};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-5='myd=$PWD;cd "`dirs -l -0`";for i in {1..5};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-6='myd=$PWD;cd "`dirs -l -0`";for i in {1..6};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-7='myd=$PWD;cd "`dirs -l -0`";for i in {1..7};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-8='myd=$PWD;cd "`dirs -l -0`";for i in {1..8};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-9='myd=$PWD;cd "`dirs -l -0`";for i in {1..9};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
# BONUS commands (beyond the 20). Aliases for navigating but NOT rotating the "navd" stack:
# Help in remembering: "navd<#>" does more since it both changes the PWD and rotates the stack, whereas "nav<#>" does less
# (and has one letter less) since "nav<#>" only changes the PWD. Also "navd<#>" acts like the pushd-related command: dirs
# There is no "nav" command (with no number) so that there will be no conflict if any program called "nav" is used.
alias nav0='cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav1='cd "`dirs -l +2`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav2='cd "`dirs -l +3`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav3='cd "`dirs -l +4`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav4='cd "`dirs -l +5`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav5='cd "`dirs -l +6`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav6='cd "`dirs -l +7`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav7='cd "`dirs -l +8`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav8='cd "`dirs -l +9`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav9='cd "`dirs -l +10`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-1='cd "`dirs -l -0`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-2='cd "`dirs -l -1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-3='cd "`dirs -l -2`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-4='cd "`dirs -l -3`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-5='cd "`dirs -l -4`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-6='cd "`dirs -l -5`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-7='cd "`dirs -l -6`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-8='cd "`dirs -l -7`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-9='cd "`dirs -l -8`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
# BONUS command (beyond the 20). Alias for showing 'history' of all navd commands that add to the stack.
# Can be used in a new terminal session to quickly add recently used dirs to the navd stack.
alias navh='if [[ ! -f $HOME/.navhignore ]]; then echo -n ''>>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/ /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "`grep -c . <(sort -u $HOME/.navhignore)`" unique lines.)"'
# Note: When 'navd <relative-path>' is used, then by bash-magic the navd command puts 'navd <absolute-path>' into history,
# instead. This allows the output of "navh" to be useful regardless of the directory that is current when it is run.
#
# BONUS commands (beyond the 20). An even shorter alias for navd. An even shorter alias for navh.
alias nd='navd'
alias nh='if [[ ! -f $HOME/.navhignore ]]; then echo -n "">>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/ /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "`grep -c . <(sort -u $HOME/.navhignore)`" unique lines.)"'
Các bí danh này dựa trên các lệnh "bash". Chăm sóc đặc biệt được thực hiện để duy trì hành vi bình thường của "cd -". (Rất nhiều thời gian tôi sử dụng "cd -" thay vì làm phiền với cả Pushd hoặc navd - bởi vì "cd -" rất tiện để quay lại "nơi" cuối cùng mà bạn đã ở hoặc chỉ chuyển đổi giữa 2 địa điểm và nó hoạt động ở mọi nơi mà không cần cài đặt.)
Tất nhiên, các lệnh này có thể được đưa vào tệp .bashrc để cài đặt chúng lâu dài hơn.
alias cd=pushd
?