squeezed gcd python part out as a file
This commit is contained in:
80
files/gcd-findmatch.py
Executable file
80
files/gcd-findmatch.py
Executable file
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys,os,re
|
||||||
|
|
||||||
|
Green="\033[32;1m"
|
||||||
|
Red="\033[31;1m"
|
||||||
|
Reset="\033[0m"
|
||||||
|
key_list="1234567890qwertyuiop"
|
||||||
|
class getch:
|
||||||
|
def get(self):
|
||||||
|
fd = sys.stdin.fileno()
|
||||||
|
old_settings = termios.tcgetattr(fd)
|
||||||
|
try:
|
||||||
|
tty.setraw(sys.stdin.fileno())
|
||||||
|
ch = sys.stdin.read(1)
|
||||||
|
finally:
|
||||||
|
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
||||||
|
return ch
|
||||||
|
def printerr(s):
|
||||||
|
sys.stderr.write(s+"\n")
|
||||||
|
sys.stderr.flush()
|
||||||
|
# Print help
|
||||||
|
if len(sys.argv)==1 or sys.argv[-1]=="-h":
|
||||||
|
printerr("Guess cd: Find first match in folder, interactive if multiple matches\n Arguments: [dir/]pattern_to_match_folders")
|
||||||
|
if sys.argv[-1]=="-h":
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
pattern=".".join(sys.argv[1:])
|
||||||
|
pat_base=os.path.basename(pattern)
|
||||||
|
pat_dir=os.path.dirname(pattern)
|
||||||
|
|
||||||
|
if pat_dir=="":
|
||||||
|
pat_dir="."
|
||||||
|
|
||||||
|
if not os.path.exists(pat_dir):
|
||||||
|
printerr("%s: %sNo such folder%s"%(pat_dir,Red,Reset))
|
||||||
|
sys.exit(1)
|
||||||
|
# list sub-folders in the folder
|
||||||
|
current_folders=[d for d in os.listdir(pat_dir) if os.path.isdir(d)]
|
||||||
|
current_folders=[d for d in current_folders if not d.startswith(".")]
|
||||||
|
current_folders.sort()
|
||||||
|
|
||||||
|
# find matches
|
||||||
|
match_case=re.compile(".*"+pat_base+".*")
|
||||||
|
repl_case=re.compile("("+pat_base+")")
|
||||||
|
|
||||||
|
matching_folders=[d for d in current_folders if match_case.match(d)]
|
||||||
|
matches=[repl_case.sub("%s\g<1>%s"%(Green,Reset),d) for d in matching_folders]
|
||||||
|
|
||||||
|
# no matches, try case insensitive
|
||||||
|
if len(matching_folders)==0:
|
||||||
|
match_nocase=re.compile(".*"+pat_base+".*",re.I)
|
||||||
|
repl_nocase=re.compile("("+pat_base+")",re.I)
|
||||||
|
matching_folders=[d for d in current_folders if match_nocase.match(d)]
|
||||||
|
matches=[repl_nocase.sub("%s\g<1>%s"%(Green,Reset),d) for d in matching_folders]
|
||||||
|
|
||||||
|
# One match, print and return
|
||||||
|
if len(matching_folders)==1:
|
||||||
|
printerr(matches[0])
|
||||||
|
print(os.path.join(pat_dir,matching_folders[0]))
|
||||||
|
sys.exit(0)
|
||||||
|
# No matches
|
||||||
|
if len(matching_folders)==0:
|
||||||
|
printerr("%sno matches%s"%(Red,Reset))
|
||||||
|
sys.exit(1)
|
||||||
|
# Many matches, ask the user for folder index
|
||||||
|
for i,m in enumerate(matches[0:len(key_list)]):
|
||||||
|
printerr(key_list[i]+": "+m)
|
||||||
|
if len(matches)>len(key_list):
|
||||||
|
printerr("Skipping the rest...")
|
||||||
|
import termios,tty
|
||||||
|
ch=getch()
|
||||||
|
key_in=ch.get()
|
||||||
|
try:
|
||||||
|
key_index=key_list.index(key_in)
|
||||||
|
key_match=matching_folders[key_index]
|
||||||
|
except (ValueError,IndexError) as err:
|
||||||
|
printerr("%s'%s' Not in the list%s"%(Red,key_in,Reset))
|
||||||
|
sys.exit(1)
|
||||||
|
print(os.path.join(pat_dir,key_match))
|
||||||
329
qcd_function
329
qcd_function
@@ -1,3 +1,33 @@
|
|||||||
|
|
||||||
|
## improved CD commands:
|
||||||
|
|
||||||
|
function gcd() {
|
||||||
|
# guess cd, find first match in folder, or ask if multiple hits
|
||||||
|
local cdto QCDPATH
|
||||||
|
QCDPATH=$( dirname ${BASH_SOURCE[0]} )
|
||||||
|
cdto=$( python "$QCDPATH"/files/gcd-findmatch.py "$@" )
|
||||||
|
[[ -z "$cdto" ]] && return
|
||||||
|
\cd "$cdto"
|
||||||
|
} # gcd ends
|
||||||
|
|
||||||
|
function hcd() {
|
||||||
|
[[ "$1" = "-h" ]] && {
|
||||||
|
echo History cd. Run without arguments to see list of entries, number as arg. to change directory.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
local d
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then tail -n 20 "$HOME/.bash_cdhistory" | head -n 19 | cut -d: -f2 | tac | cat -n | sed 's,^ \+,,' | tac
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
d=$( tail -n 20 "$HOME/.bash_cdhistory" | head -n 19 | cut -d: -f2 | tac | cat -n | sed 's,^ \+,,' | grep -h "^$1 " )
|
||||||
|
d=${d/* /}
|
||||||
|
if [ ! -z "$d" ]
|
||||||
|
then \cd "$d"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function cd_history () {
|
function cd_history () {
|
||||||
# Function that replaces "cd". It stores visited folder in ~/.bash_cdhistory
|
# Function that replaces "cd". It stores visited folder in ~/.bash_cdhistory
|
||||||
local old
|
local old
|
||||||
@@ -17,21 +47,6 @@ function cd_history () {
|
|||||||
}
|
}
|
||||||
alias cd=cd_history
|
alias cd=cd_history
|
||||||
|
|
||||||
function hcd() {
|
|
||||||
# History cd. Run without arguments to see list of entries, give number to change cwd.
|
|
||||||
local d
|
|
||||||
|
|
||||||
if [ -z "$1" ]
|
|
||||||
then tail -n 20 "$HOME/.bash_cdhistory" | head -n 19 | cut -d: -f2 | tac | cat -n | sed 's,^ \+,,' | tac
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
d=$( tail -n 20 "$HOME/.bash_cdhistory" | head -n 19 | cut -d: -f2 | tac | cat -n | sed 's,^ \+,,' | grep -h "^$1 " )
|
|
||||||
d=${d/* /}
|
|
||||||
if [ ! -z "$d" ]
|
|
||||||
then \cd "$d"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function qcd() {
|
function qcd() {
|
||||||
# cd command, that jumps to folders visited in the near history, or user bookmarked folders
|
# cd command, that jumps to folders visited in the near history, or user bookmarked folders
|
||||||
local OPTIND
|
local OPTIND
|
||||||
@@ -120,7 +135,7 @@ complete -F _qcd qcd
|
|||||||
;;
|
;;
|
||||||
h)
|
h)
|
||||||
echo 'qcd [-hiLm]|[-al] [name]
|
echo 'qcd [-hiLm]|[-al] [name]
|
||||||
Version: 2015-10-13
|
Version: 2017-03-24
|
||||||
Change current working path based on the list ~/.qcd
|
Change current working path based on the list ~/.qcd
|
||||||
Keeps a history of folders visited in ~/.bash_cdhistory
|
Keeps a history of folders visited in ~/.bash_cdhistory
|
||||||
|
|
||||||
@@ -156,6 +171,112 @@ Keeps a history of folders visited in ~/.bash_cdhistory
|
|||||||
then \cd "$d"
|
then \cd "$d"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
} # qcd ends
|
||||||
|
|
||||||
|
function ncd() {
|
||||||
|
[[ "$1" = "-h" ]] && {
|
||||||
|
echo Next sibling cd: change directory to [../next_folder]. ncd - to go to previous.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
local _current_pwd _iter_d _iter_prev _current_found
|
||||||
|
_current_pwd=$( basename $( pwd ) )
|
||||||
|
\cd ..
|
||||||
|
for _iter_d in *; do
|
||||||
|
if [ ! -d "$_iter_d" ]; then continue; fi
|
||||||
|
if [ -n "$_current_found" ]; then
|
||||||
|
\cd "$_iter_d"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ "$_iter_d" = "$_current_pwd" ]; then
|
||||||
|
_current_found=true
|
||||||
|
if [ "$1" = "-" ]; then
|
||||||
|
if [ -z "$_iter_prev" ]; then
|
||||||
|
echo $_current_pwd was the first folder.
|
||||||
|
else
|
||||||
|
\cd "$_iter_prev";
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_iter_prev="$_iter_d"
|
||||||
|
done
|
||||||
|
if [ -n "$_current_found" ]; then
|
||||||
|
echo "$_current_pwd" was the last folder.
|
||||||
|
else
|
||||||
|
echo "$_current_pwd" was not found in ../
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## File processing functions
|
||||||
|
|
||||||
|
function foldermenu_prompt {
|
||||||
|
# Function to add in PS prompt variable, enabling foldermenu support
|
||||||
|
[ -f .foldermenu ] && {
|
||||||
|
foldermenu -lf 10 $@ || echo -n "*"
|
||||||
|
} || {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function igrep () {
|
||||||
|
[[ "$1" = "-h" ]] && [[ "$#" -eq 1 ]] && {
|
||||||
|
echo Interactive grep, read grep arguments
|
||||||
|
return
|
||||||
|
}
|
||||||
|
local args
|
||||||
|
args="-i -e "
|
||||||
|
while true
|
||||||
|
do read -e -i "$args" args
|
||||||
|
echo $@
|
||||||
|
grep --color=auto $args "$@"
|
||||||
|
if [ "$?" -ne 0 ]
|
||||||
|
then echo _no_matches_ | grep --color=auto ".*"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function ised () {
|
||||||
|
[[ "$1" = "-h" ]] && [[ "$#" -eq 1 ]] && {
|
||||||
|
echo Interactive sed, read sed arguments
|
||||||
|
return
|
||||||
|
}
|
||||||
|
local args
|
||||||
|
if [ ! -f "$1" ]; then echo must give atleast one file; return 1;fi;
|
||||||
|
args="-e s/string//g"
|
||||||
|
while true
|
||||||
|
do read -e -i "$args" args
|
||||||
|
echo input files: "$@"
|
||||||
|
eval sed $args "$@"
|
||||||
|
if [ "$?" -ne 0 ]
|
||||||
|
then echo Error output | grep --color=auto ".*"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function rmv () {
|
||||||
|
[[ "$1" = "-h" ]] && {
|
||||||
|
echo 'mv files/folders with rsync (shows speed and progress)'
|
||||||
|
echo 'Usage: rmv source [source2] [source3] target'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
local sources
|
||||||
|
sources=()
|
||||||
|
# remove / from ends, if target is an existing folder
|
||||||
|
for (( i=1; i<=$(($#-1)); i++ ))
|
||||||
|
do if [ -d "${@: -1}" ]
|
||||||
|
then sources+=("${!i%/}")
|
||||||
|
else sources+=("${!i}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
rsync -vaP --remove-source-files "${sources[@]}" "${@: -1}"
|
||||||
|
# remove empty folders from sources (not last argument)
|
||||||
|
for (( i=1; i<=$(($#-1)); i++ ))
|
||||||
|
do if [ -d "${!i}" ]
|
||||||
|
then find "${!i}" -depth -type d -exec rmdir \{\} \;
|
||||||
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function whenfilechanges() {
|
function whenfilechanges() {
|
||||||
@@ -205,184 +326,22 @@ function whenfilechanges() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function gcd() {
|
# Shell enhancement
|
||||||
# guess cd, find first match in folder, or ask if multiple hits
|
|
||||||
local cdto
|
|
||||||
{ cdto=$( python -c '
|
|
||||||
import sys,os,re
|
|
||||||
if len(sys.argv)==1 or sys.argv[-1]=="-h":
|
|
||||||
print("Arguments: [dir/]pattern_to_match_folders")
|
|
||||||
if sys.argv[-1]=="-h":
|
|
||||||
sys.exit(0)
|
|
||||||
def G():
|
|
||||||
return "\033[32;1m"
|
|
||||||
def R():
|
|
||||||
return "\033[31;1m"
|
|
||||||
def Z():
|
|
||||||
return "\033[0m"
|
|
||||||
def CS():
|
|
||||||
return "1234567890qwertyuiop"
|
|
||||||
class getch:
|
|
||||||
def get(self):
|
|
||||||
fd = sys.stdin.fileno()
|
|
||||||
old_settings = termios.tcgetattr(fd)
|
|
||||||
try:
|
|
||||||
tty.setraw(sys.stdin.fileno())
|
|
||||||
ch = sys.stdin.read(1)
|
|
||||||
finally:
|
|
||||||
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
|
||||||
return ch
|
|
||||||
|
|
||||||
pattern=".".join(sys.argv[1:])
|
|
||||||
|
|
||||||
pat_dir=os.path.dirname(pattern)
|
|
||||||
if pat_dir=="":
|
|
||||||
pat_dir="."
|
|
||||||
pat_base=os.path.basename(pattern)
|
|
||||||
if not os.path.exists(pat_dir):
|
|
||||||
print(pat_dir+": "+R()+"No such folder"+Z())
|
|
||||||
sys.exit(1)
|
|
||||||
current_folders=[d for d in os.listdir(pat_dir) if os.path.isdir(d)]
|
|
||||||
current_folders=[d for d in current_folders if not d.startswith(".")]
|
|
||||||
current_folders.sort()
|
|
||||||
|
|
||||||
match_case=re.compile(".*"+pat_base+".*")
|
|
||||||
repl_case=re.compile("("+pat_base+")")
|
|
||||||
|
|
||||||
matching_folders=[d for d in current_folders if match_case.match(d)]
|
|
||||||
matches=[repl_case.sub(G()+"\g<1>"+Z(),d) for d in matching_folders]
|
|
||||||
|
|
||||||
if len(matching_folders)==0:
|
|
||||||
match_nocase=re.compile(".*"+pat_base+".*",re.I)
|
|
||||||
repl_nocase=re.compile("("+pat_base+")",re.I)
|
|
||||||
matching_folders=[d for d in current_folders if match_nocase.match(d)]
|
|
||||||
matches=[repl_nocase.sub(G()+"\g<1>"+Z(),d) for d in matching_folders]
|
|
||||||
|
|
||||||
if len(matching_folders)==1:
|
|
||||||
print(matches[0])
|
|
||||||
sys.stderr.write(os.path.join(pat_dir,matching_folders[0]))
|
|
||||||
sys.exit(0)
|
|
||||||
if len(matching_folders)==0:
|
|
||||||
print(R()+"no matches"+Z())
|
|
||||||
sys.exit(1)
|
|
||||||
for i,m in enumerate(matches[0:20]):
|
|
||||||
print(CS()[i]+": "+m)
|
|
||||||
if len(matches)>20:
|
|
||||||
print("Skipping rest...")
|
|
||||||
import termios,tty
|
|
||||||
ch=getch()
|
|
||||||
key_in=ch.get()
|
|
||||||
try:
|
|
||||||
key_index=CS().index(key_in)
|
|
||||||
key_match=matching_folders[key_index]
|
|
||||||
except ValueError,IndexError:
|
|
||||||
sys.exit(1)
|
|
||||||
sys.stderr.write(os.path.join(pat_dir,key_match))
|
|
||||||
' "$@" 2>&1 1>&$out); } {out}>&1 ; \cd "$cdto"
|
|
||||||
}
|
|
||||||
|
|
||||||
function ncd() {
|
|
||||||
# Next cd: cd to ../[next_folder]. ncd - to go to previous
|
|
||||||
local _current_pwd _iter_d _iter_prev _current_found
|
|
||||||
_current_pwd=$( basename $( pwd ) )
|
|
||||||
\cd ..
|
|
||||||
for _iter_d in *; do
|
|
||||||
if [ ! -d "$_iter_d" ]; then continue; fi
|
|
||||||
if [ -n "$_current_found" ]; then
|
|
||||||
\cd "$_iter_d"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
if [ "$_iter_d" = "$_current_pwd" ]; then
|
|
||||||
_current_found=true
|
|
||||||
if [ "$1" = "-" ]; then
|
|
||||||
if [ -z "$_iter_prev" ]; then
|
|
||||||
echo $_current_pwd was the first folder.
|
|
||||||
else
|
|
||||||
\cd "$_iter_prev";
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
_iter_prev="$_iter_d"
|
|
||||||
done
|
|
||||||
if [ -n "$_current_found" ]; then
|
|
||||||
echo "$_current_pwd" was the last folder.
|
|
||||||
else
|
|
||||||
echo "$_current_pwd" was not found in ../
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function rmv () {
|
|
||||||
# mv files/folders with rsync (shows speed and progress)
|
|
||||||
local sources
|
|
||||||
sources=()
|
|
||||||
# remove / from ends, if target is an existing folder
|
|
||||||
for (( i=1; i<=$(($#-1)); i++ ))
|
|
||||||
do if [ -d "${@: -1}" ]
|
|
||||||
then sources+=("${!i%/}")
|
|
||||||
else sources+=("${!i}")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
rsync -vaP --remove-source-files "${sources[@]}" "${@: -1}"
|
|
||||||
# remove empty folders from sources (not last argument)
|
|
||||||
for (( i=1; i<=$(($#-1)); i++ ))
|
|
||||||
do if [ -d "${!i}" ]
|
|
||||||
then find "${!i}" -depth -type d -exec rmdir \{\} \;
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function igrep () {
|
|
||||||
# Interactive grep
|
|
||||||
local args
|
|
||||||
args="-i -e "
|
|
||||||
while true
|
|
||||||
do read -e -i "$args" args
|
|
||||||
echo $@
|
|
||||||
grep --color=auto $args "$@"
|
|
||||||
if [ "$?" -ne 0 ]
|
|
||||||
then echo _no_matches_ | grep --color=auto ".*"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function ised () {
|
|
||||||
# Interactive sed
|
|
||||||
local args
|
|
||||||
if [ ! -f "$1" ]; then echo must give atleast one file; return 1;fi;
|
|
||||||
args="-e s/string//g"
|
|
||||||
while true
|
|
||||||
do read -e -i "$args" args
|
|
||||||
echo input files: "$@"
|
|
||||||
eval sed $args "$@"
|
|
||||||
if [ "$?" -ne 0 ]
|
|
||||||
then echo Error output | grep --color=auto ".*"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function foldermenu_prompt {
|
|
||||||
# Function to add in PS prompt variable, enabling foldermenu support
|
|
||||||
[ -f .foldermenu ] && {
|
|
||||||
foldermenu -lf 10 $@ || echo -n "*"
|
|
||||||
} || {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function qbg {
|
function qbg {
|
||||||
# Run a program quiet, and backgrounded
|
[[ "$1" = "-h" ]] && {
|
||||||
|
echo 'Run a command quiet, and backgrounded ( typically X11 executable )'
|
||||||
|
return
|
||||||
|
}
|
||||||
"$@" &> /dev/null &
|
"$@" &> /dev/null &
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_term_title {
|
function set_term_title {
|
||||||
# set term in byobu/screen xterm etc..
|
# set term in byobu/screen xterm etc..
|
||||||
[ -z "$1" ] && {
|
[ -z "$1" ] && {
|
||||||
echo -e '\033k'$HOSTNAME'\033\\'
|
echo -ne '\033k'$HOSTNAME'\033\\\r'
|
||||||
} || {
|
} || {
|
||||||
echo -e '\033k'$1'\033\\'
|
echo -ne '\033k'$1'\033\\\r'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user