Imported from ../bash-2.05b.tar.gz.
This commit is contained in:
parent
f73dda092b
commit
7117c2d221
362 changed files with 34387 additions and 15063 deletions
596
examples/bashdb/bashdb
Normal file → Executable file
596
examples/bashdb/bashdb
Normal file → Executable file
|
|
@ -1,33 +1,581 @@
|
|||
# kshdb - Korn Shell Debugger main file
|
||||
# adapted from 'Learning the Korn Shell' by Bill Rosenblatt (O'Reilly)
|
||||
# by Cigy Cyriac (cigy@felix.tulblr.unisys.com)
|
||||
# Main driver: constructs full script (with preamble) and runs it
|
||||
#! /bin/bash
|
||||
# bashdb - Bash shell debugger
|
||||
#
|
||||
# Adapted from an idea in O'Reilly's `Learning the Korn Shell'
|
||||
# Copyright (C) 1993-1994 O'Reilly and Associates, Inc.
|
||||
# Copyright (C) 1998, 1999, 2001 Gary V. Vaughan <gvv@techie.com>>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
echo 'Bourne-Again Shell Debugger version 0.1'
|
||||
# NOTE:
|
||||
#
|
||||
# This program requires bash 2.x.
|
||||
# If bash 2.x is installed as "bash2", you can invoke bashdb like this:
|
||||
#
|
||||
# DEBUG_SHELL=/bin/bash2 /bin/bash2 bashdb script.sh
|
||||
|
||||
_pname=${0##*/}
|
||||
# TODO:
|
||||
#
|
||||
# break [regexp]
|
||||
# cond [break] [condition]
|
||||
# tbreak [regexp|+lines]
|
||||
# restart
|
||||
# Variable watchpoints
|
||||
# Instrument `source' and `.' files in $_potbelliedpig
|
||||
# be cleverer about lines we allow breakpoints to be set on
|
||||
# break [function_name]
|
||||
|
||||
[ $# -eq 0 ] && {
|
||||
echo "${_pname}: usage: ${_pname} <script_file>"
|
||||
exit 1
|
||||
}
|
||||
echo 'Bash Debugger version 1.2.4'
|
||||
|
||||
export _dbname=${0##*/}
|
||||
|
||||
if test $# -lt 1; then
|
||||
echo "$_dbname: Usage: $_dbname filename" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_guineapig=$1
|
||||
|
||||
[ -r $_guineapig ] || {
|
||||
echo "${_pname}: cannot read $_guineapig." >&2
|
||||
exit 1
|
||||
}
|
||||
if test ! -r $1; then
|
||||
echo "$_dbname: Cannot read file '$_guineapig'." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
|
||||
_tmpdir=/tmp
|
||||
_libdir=.
|
||||
_dbgfile=$_tmpdir/bashdb$$ #temp file for script being debugged
|
||||
__debug=${TMPDIR-/tmp}/bashdb.$$
|
||||
sed -e '/^# bashdb - Bash shell debugger/,/^# -- DO NOT DELETE THIS LINE -- /d' "$0" > $__debug
|
||||
cat $_guineapig >> $__debug
|
||||
exec ${DEBUG_SHELL-bash} $__debug $_guineapig "$@"
|
||||
|
||||
cat $_libdir/bashdb.pre $_guineapig > $_dbgfile
|
||||
if [ -f "$BASH" ]; then
|
||||
exec $BASH $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
|
||||
else
|
||||
exec bash $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
|
||||
fi
|
||||
# end of bashdb
|
||||
exit 1
|
||||
|
||||
# -- DO NOT DELETE THIS LINE -- The program depends on it
|
||||
|
||||
#bashdb preamble
|
||||
# $1 name of the original guinea pig script
|
||||
|
||||
__debug=$0
|
||||
_guineapig=$1
|
||||
__steptrap_calls=0
|
||||
|
||||
shift
|
||||
|
||||
shopt -s extglob # turn on extglob so we can parse the debugger funcs
|
||||
|
||||
function _steptrap
|
||||
{
|
||||
local i=0
|
||||
|
||||
_curline=$1
|
||||
|
||||
if (( ++__steptrap_calls > 1 && $_curline == 1 )); then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$_disps" ]; then
|
||||
while (( $i < ${#_disps[@]} ))
|
||||
do
|
||||
if [ -n "${_disps[$i]}" ]; then
|
||||
_msg "${_disps[$i]}: \c"
|
||||
eval _msg ${_disps[$i]}
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
fi
|
||||
|
||||
if (( $_trace )); then
|
||||
_showline $_curline
|
||||
fi
|
||||
|
||||
if (( $_steps >= 0 )); then
|
||||
let _steps="$_steps - 1"
|
||||
fi
|
||||
|
||||
if _at_linenumbp ; then
|
||||
_msg "Reached breakpoint at line $_curline"
|
||||
_showline $_curline
|
||||
_cmdloop
|
||||
elif [ -n "$_brcond" ] && eval $_brcond; then
|
||||
_msg "Break condition $_brcond true at line $_curline"
|
||||
_showline $_curline
|
||||
_cmdloop
|
||||
elif (( $_steps == 0 )); then
|
||||
# Assuming a real script will have the "#! /bin/sh" at line 1,
|
||||
# assume that when $_curline == 1 we are inside backticks.
|
||||
if (( ! $_trace )); then
|
||||
_msg "Stopped at line $_curline"
|
||||
_showline $_curline
|
||||
fi
|
||||
_cmdloop
|
||||
fi
|
||||
}
|
||||
|
||||
function _setbp
|
||||
{
|
||||
local i f line _x
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
_listbp
|
||||
return
|
||||
fi
|
||||
|
||||
eval "$_seteglob"
|
||||
|
||||
if [[ $1 == *(\+)[1-9]*([0-9]) ]]; then
|
||||
case $1 in
|
||||
+*)
|
||||
# normalize argument, then double it (+2 -> +2 + 2 = 4)
|
||||
_x=${1##*([!1-9])} # cut off non-numeric prefix
|
||||
_x=${x%%*([!0-9])} # cut off non-numeric suffix
|
||||
f=$(( $1 + $_x ))
|
||||
;;
|
||||
*)
|
||||
f=$(( $1 ))
|
||||
;;
|
||||
esac
|
||||
|
||||
# find the next valid line
|
||||
line="${_lines[$f]}"
|
||||
while _invalidbreakp $f
|
||||
do
|
||||
(( f++ ))
|
||||
line="${_lines[$f]}"
|
||||
done
|
||||
|
||||
if (( $f != $1 ))
|
||||
then
|
||||
_msg "Line $1 is not a valid breakpoint"
|
||||
fi
|
||||
|
||||
if [ -n "${_lines[$f]}" ]; then
|
||||
_linebp[$1]=$1;
|
||||
_msg "Breakpoint set at line $f"
|
||||
else
|
||||
_msg "Breakpoints can only be set on executable lines"
|
||||
fi
|
||||
else
|
||||
_msg "Please specify a numeric line number"
|
||||
fi
|
||||
|
||||
eval "$_resteglob"
|
||||
}
|
||||
|
||||
function _listbp
|
||||
{
|
||||
local i
|
||||
|
||||
if [ -n "$_linebp" ]; then
|
||||
_msg "Breakpoints:"
|
||||
for i in ${_linebp[*]}; do
|
||||
_showline $i
|
||||
done
|
||||
else
|
||||
_msg "No breakpoints have been set"
|
||||
fi
|
||||
}
|
||||
|
||||
function _clearbp
|
||||
{
|
||||
local i
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
read -e -p "Delete all breakpoints? "
|
||||
case $REPLY in
|
||||
[yY]*)
|
||||
unset _linebp[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
fi
|
||||
|
||||
eval "$_seteglob"
|
||||
|
||||
if [[ $1 == [1-9]*([0-9]) ]]; then
|
||||
unset _linebp[$1]
|
||||
_msg "Breakpoint cleared at line $1"
|
||||
else
|
||||
_msg "Please specify a numeric line number"
|
||||
fi
|
||||
|
||||
eval "$_resteglob"
|
||||
}
|
||||
|
||||
function _setbc
|
||||
{
|
||||
if (( $# > 0 )); then
|
||||
_brcond=$@
|
||||
_msg "Break when true: $_brcond"
|
||||
else
|
||||
_brcond=
|
||||
_msg "Break condition cleared"
|
||||
fi
|
||||
}
|
||||
|
||||
function _setdisp
|
||||
{
|
||||
if [ -z "$1" ]; then
|
||||
_listdisp
|
||||
else
|
||||
_disps[${#_disps[@]}]="$1"
|
||||
if (( ${#_disps[@]} < 10 ))
|
||||
then
|
||||
_msg " ${#_disps[@]}: $1"
|
||||
else
|
||||
_msg "${#_disps[@]}: $1"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function _listdisp
|
||||
{
|
||||
local i=0 j
|
||||
|
||||
if [ -n "$_disps" ]; then
|
||||
while (( $i < ${#_disps[@]} ))
|
||||
do
|
||||
let j=$i+1
|
||||
if (( ${#_disps[@]} < 10 ))
|
||||
then
|
||||
_msg " $j: ${_disps[$i]}"
|
||||
else
|
||||
_msg "$j: ${_disps[$i]}"
|
||||
fi
|
||||
let i=$j
|
||||
done
|
||||
else
|
||||
_msg "No displays have been set"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cleardisp
|
||||
{
|
||||
if (( $# < 1 )) ; then
|
||||
read -e -p "Delete all display expressions? "
|
||||
case $REPLY in
|
||||
[Yy]*)
|
||||
unset _disps[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
fi
|
||||
|
||||
eval "$_seteglob"
|
||||
|
||||
if [[ $1 == [1-9]*([0-9]) ]]; then
|
||||
unset _disps[$1]
|
||||
_msg "Display $i has been cleared"
|
||||
else
|
||||
_listdisp
|
||||
_msg "Please specify a numeric display number"
|
||||
fi
|
||||
|
||||
eval "$_resteglob"
|
||||
}
|
||||
|
||||
# usage _ftrace -u funcname [funcname...]
|
||||
function _ftrace
|
||||
{
|
||||
local _opt=-t _tmsg="enabled" _func
|
||||
if [[ $1 == -u ]]; then
|
||||
_opt=+t
|
||||
_tmsg="disabled"
|
||||
shift
|
||||
fi
|
||||
for _func; do
|
||||
declare -f $_opt $_func
|
||||
_msg "Tracing $_tmsg for function $_func"
|
||||
done
|
||||
}
|
||||
|
||||
function _cmdloop
|
||||
{
|
||||
local cmd args
|
||||
|
||||
while read -e -p "bashdb> " cmd args; do
|
||||
test -n "$cmd" && history -s "$cmd $args" # save on history list
|
||||
test -n "$cmd" || { set $_lastcmd; cmd=$1; shift; args=$*; }
|
||||
if [ -n "$cmd" ]
|
||||
then
|
||||
case $cmd in
|
||||
b|br|bre|brea|break)
|
||||
_setbp $args
|
||||
_lastcmd="break $args"
|
||||
;;
|
||||
co|con)
|
||||
_msg "ambiguous command: '$cmd', condition, continue?"
|
||||
;;
|
||||
cond|condi|condit|conditi|conditio|condition)
|
||||
_setbc $args
|
||||
_lastcmd="condition $args"
|
||||
;;
|
||||
c|cont|conti|contin|continu|continue)
|
||||
_lastcmd="continue"
|
||||
return
|
||||
;;
|
||||
d)
|
||||
_msg "ambiguous command: '$cmd', delete, display?"
|
||||
;;
|
||||
de|del|dele|delet|delete)
|
||||
_clearbp $args
|
||||
_lastcmd="delete $args"
|
||||
;;
|
||||
di|dis|disp|displ|displa|display)
|
||||
_setdisp $args
|
||||
_lastcmd="display $args"
|
||||
;;
|
||||
f|ft|ftr|ftra|ftrace)
|
||||
_ftrace $args
|
||||
_lastcmd="ftrace $args"
|
||||
;;
|
||||
\?|h|he|hel|help)
|
||||
_menu
|
||||
_lastcmd="help"
|
||||
;;
|
||||
l|li|lis|list)
|
||||
_displayscript $args
|
||||
# _lastcmd is set in the _displayscript function
|
||||
;;
|
||||
p|pr|pri|prin|print)
|
||||
_examine $args
|
||||
_lastcmd="print $args"
|
||||
;;
|
||||
q|qu|qui|quit)
|
||||
exit
|
||||
;;
|
||||
s|st|ste|step|n|ne|nex|next)
|
||||
let _steps=${args:-1}
|
||||
_lastcmd="next $args"
|
||||
return
|
||||
;;
|
||||
t|tr|tra|trac|trace)
|
||||
_xtrace
|
||||
;;
|
||||
u|un|und|undi|undis|undisp|undispl|undispla|undisplay)
|
||||
_cleardisp $args
|
||||
_lastcmd="undisplay $args"
|
||||
;;
|
||||
!*)
|
||||
eval ${cmd#!} $args
|
||||
_lastcmd="$cmd $args"
|
||||
;;
|
||||
*)
|
||||
_msg "Invalid command: '$cmd'"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function _at_linenumbp
|
||||
{
|
||||
[[ -n ${_linebp[$_curline]} ]]
|
||||
}
|
||||
|
||||
function _invalidbreakp
|
||||
{
|
||||
local line=${_lines[$1]}
|
||||
|
||||
# XXX - should use shell patterns
|
||||
if test -z "$line" \
|
||||
|| expr "$line" : '[ \t]*#.*' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*;;[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*;;[ \t]*#.**$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;*[ \t]*#.*$' > /dev/null
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function _examine
|
||||
{
|
||||
if [ -n "$*" ]; then
|
||||
_msg "$args: \c"
|
||||
eval _msg $args
|
||||
else
|
||||
_msg "Nothing to print"
|
||||
fi
|
||||
}
|
||||
|
||||
function _displayscript
|
||||
{
|
||||
local i j start end bp cl
|
||||
|
||||
if (( $# == 1 )); then # list 5 lines on either side of $1
|
||||
if [ $1 = "%" ]; then
|
||||
let start=1
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let start=$1-5
|
||||
let end=$1+5
|
||||
fi
|
||||
elif (( $# > 1 )); then # list between start and end
|
||||
if [ $1 = "^" ]; then
|
||||
let start=1
|
||||
else
|
||||
let start=$1
|
||||
fi
|
||||
|
||||
if [ $2 = "\$" ]; then
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let end=$2
|
||||
fi
|
||||
else # list 5 lines on either side of current line
|
||||
let start=$_curline-5
|
||||
let end=$_curline+5
|
||||
fi
|
||||
|
||||
# normalize start and end
|
||||
if (( $start < 1 )); then
|
||||
start=1
|
||||
fi
|
||||
if (( $end > ${#_lines[@]} )); then
|
||||
end=${#_lines[@]}
|
||||
fi
|
||||
|
||||
cl=$(( $end - $start ))
|
||||
if (( $cl > ${LINES-24} )); then
|
||||
pager=${PAGER-more}
|
||||
else
|
||||
pager=cat
|
||||
fi
|
||||
|
||||
i=$start
|
||||
( while (( $i <= $end )); do
|
||||
_showline $i
|
||||
let i=$i+1
|
||||
done ) 2>&1 | $pager
|
||||
|
||||
# calculate the next block of lines
|
||||
start=$(( $end + 1 ))
|
||||
end=$(( $start + 11 ))
|
||||
if (( $end > ${#_lines[@]} ))
|
||||
then
|
||||
end=${#_lines[@]}
|
||||
fi
|
||||
|
||||
_lastcmd="list $start $end"
|
||||
}
|
||||
|
||||
function _xtrace
|
||||
{
|
||||
let _trace="! $_trace"
|
||||
if (( $_trace )); then
|
||||
_msg "Execution trace on"
|
||||
else
|
||||
_msg "Execution trace off"
|
||||
fi
|
||||
}
|
||||
|
||||
function _msg
|
||||
{
|
||||
echo -e "$@" >&2
|
||||
}
|
||||
|
||||
function _showline
|
||||
{
|
||||
local i=0 bp=' ' line=$1 cl=' '
|
||||
|
||||
if [[ -n ${_linebp[$line]} ]]; then
|
||||
bp='*'
|
||||
fi
|
||||
|
||||
if (( $_curline == $line )); then
|
||||
cl=">"
|
||||
fi
|
||||
|
||||
if (( $line < 100 )); then
|
||||
_msg "$_guineapig:$line $bp $cl${_lines[$line]}"
|
||||
elif (( $line < 10 )); then
|
||||
_msg "$_guineapig:$line $bp $cl${_lines[$line]}"
|
||||
elif (( $line > 0 )); then
|
||||
_msg "$_guineapig:$line $bp $cl${_lines[$line]}"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cleanup
|
||||
{
|
||||
rm -f $__debug $_potbelliedpig 2> /dev/null
|
||||
}
|
||||
|
||||
function _menu
|
||||
{
|
||||
_msg 'bashdb commands:
|
||||
break N set breakpoint at line N
|
||||
break list breakpoints & break condition
|
||||
condition foo set break condition to foo
|
||||
condition clear break condition
|
||||
delete N clear breakpoint at line N
|
||||
delete clear all breakpoints
|
||||
display EXP evaluate and display EXP for each debug step
|
||||
display show a list of display expressions
|
||||
undisplay N remove display expression N
|
||||
list N M display all lines of script between N and M
|
||||
list N display 5 lines of script either side of line N
|
||||
list display 5 lines if script either side of current line
|
||||
continue continue execution upto next breakpoint
|
||||
next [N] execute [N] statements (default 1)
|
||||
print expr prints the value of an expression
|
||||
trace toggle execution trace on/off
|
||||
ftrace [-u] func make the debugger step into function FUNC
|
||||
(-u turns off tracing FUNC)
|
||||
help print this menu
|
||||
! string passes string to a shell
|
||||
quit quit'
|
||||
}
|
||||
|
||||
shopt -u extglob
|
||||
|
||||
HISTFILE=~/.bashdb_history
|
||||
set -o history
|
||||
set +H
|
||||
|
||||
# strings to save and restore the setting of `extglob' in debugger functions
|
||||
# that need it
|
||||
_seteglob='local __eopt=-u ; shopt -q extglob && __eopt=-s ; shopt -s extglob'
|
||||
_resteglob='shopt $__eopt extglob'
|
||||
|
||||
_linebp=()
|
||||
let _trace=0
|
||||
let _i=1
|
||||
|
||||
# Be careful about quoted newlines
|
||||
_potbelliedpig=${TMPDIR-/tmp}/$_guineapig.$$
|
||||
sed 's,\\$,\\\\,' $_guineapig > $_potbelliedpig
|
||||
|
||||
_msg "Reading source from file: $_guineapig"
|
||||
while read; do
|
||||
_lines[$_i]=$REPLY
|
||||
let _i=$_i+1
|
||||
done < $_potbelliedpig
|
||||
|
||||
trap _cleanup EXIT
|
||||
# Assuming a real script will have the "#! /bin/sh" at line 1,
|
||||
# don't stop at line 1 on the first run
|
||||
let _steps=1
|
||||
LINENO=-1
|
||||
trap '_steptrap $LINENO' DEBUG
|
||||
|
|
|
|||
177
examples/bashdb/bashdb.el
Normal file
177
examples/bashdb/bashdb.el
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
;;; bashdb.el --- Grand Unified Debugger mode for running bashdb
|
||||
;; Copyright (C) 2000, 2001 Masatake YAMATO
|
||||
|
||||
;; Author: Masatake YAMATO <jet@gyve.org>
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful, but
|
||||
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program; if not, write to the Free Software Foundation,
|
||||
;; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
;; Commentary:
|
||||
;; This program may run on Emacs 21.0.91 and XEmacs 21.1.
|
||||
;;
|
||||
;; Put
|
||||
;; (autoload 'bashdb "bashdb" "Run bashdb" t nil)
|
||||
;; to your .emacs.
|
||||
;; M-x bashdb
|
||||
;; Run bashdb (like this): bashdb target.sh
|
||||
;;
|
||||
;; About bashdb:
|
||||
;; You can get bashdb from
|
||||
;; http://www.oranda.demon.co.uk/development.html
|
||||
;;
|
||||
;; bashdb.el is based on perldb in gud.el in XEmacs 21.1.
|
||||
|
||||
;; Revision:
|
||||
;; $Revision: 1.6 $
|
||||
;; $Log: bashdb.el,v $
|
||||
;; Revision 1.6 2001/01/06 12:18:06 masata-y
|
||||
;; Write note about XEmacs.
|
||||
;;
|
||||
;;
|
||||
|
||||
|
||||
;;; Code:
|
||||
(require 'gud)
|
||||
|
||||
;; User customizable variable
|
||||
(defcustom gud-bashdb-command-name "bashdb"
|
||||
"File name for executing Bashdb."
|
||||
:type 'string
|
||||
:group 'gud)
|
||||
|
||||
;; History of argument lists passed to bashdb.
|
||||
(defvar gud-bashdb-history nil)
|
||||
|
||||
(defun gud-bashdb-massage-args (file args)
|
||||
(if xemacsp
|
||||
(cons (file-name-nondirectory file) args)
|
||||
args))
|
||||
|
||||
;; There's no guarantee that Emacs will hand the filter the entire
|
||||
;; marker at once; it could be broken up across several strings. We
|
||||
;; might even receive a big chunk with several markers in it. If we
|
||||
;; receive a chunk of text which looks like it might contain the
|
||||
;; beginning of a marker, we save it here between calls to the
|
||||
;; filter.
|
||||
(if xemacsp
|
||||
(defvar gud-bashdb-marker-acc ""))
|
||||
(defun gud-bashdb-marker-acc ()
|
||||
(if xemacsp
|
||||
gud-bashdb-marker-acc
|
||||
gud-marker-acc))
|
||||
(defun gud-bashdb-marker-acc-quote ()
|
||||
(if xemacsp
|
||||
'gud-bashdb-marker-acc
|
||||
'gud-marker-acc))
|
||||
|
||||
(defun gud-bashdb-marker-filter (string)
|
||||
(save-match-data
|
||||
(set (gud-bashdb-marker-acc-quote)
|
||||
(concat (gud-bashdb-marker-acc) string))
|
||||
(let ((output ""))
|
||||
;; Process all the complete markers in this chunk.
|
||||
(while (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>.*\n"
|
||||
(gud-bashdb-marker-acc))
|
||||
(setq
|
||||
;; Extract the frame position from the marker.
|
||||
gud-last-frame (cons
|
||||
(substring (gud-bashdb-marker-acc)
|
||||
(match-beginning 1)
|
||||
(match-end 1))
|
||||
(string-to-int
|
||||
(substring (gud-bashdb-marker-acc)
|
||||
(match-beginning 2)
|
||||
(match-end 2))))
|
||||
;; Append any text before the marker to the output we're going
|
||||
;; to return - we don't include the marker in this text.
|
||||
output (concat output
|
||||
(substring (gud-bashdb-marker-acc) 0 (match-beginning 0))))
|
||||
;; Set the accumulator to the remaining text.
|
||||
(set
|
||||
(gud-bashdb-marker-acc-quote) (substring
|
||||
(gud-bashdb-marker-acc) (match-end 0))))
|
||||
|
||||
;; Does the remaining text look like it might end with the
|
||||
;; beginning of another marker? If it does, then keep it in
|
||||
;; (gud-bashdb-marker-acc) until we receive the rest of it. Since we
|
||||
;; know the full marker regexp above failed, it's pretty simple to
|
||||
;; test for marker starts.
|
||||
(if (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>" (gud-bashdb-marker-acc))
|
||||
(progn
|
||||
;; Everything before the potential marker start can be output.
|
||||
(setq output (concat output (substring (gud-bashdb-marker-acc)
|
||||
0 (match-beginning 0))))
|
||||
;; Everything after, we save, to combine with later input.
|
||||
(set (gud-bashdb-marker-acc-quote)
|
||||
(substring (gud-bashdb-marker-acc) (match-beginning 0))))
|
||||
|
||||
(setq output (concat output (gud-bashdb-marker-acc)))
|
||||
(set (gud-bashdb-marker-acc-quote) ""))
|
||||
|
||||
output)))
|
||||
|
||||
(defun gud-bashdb-find-file (f)
|
||||
(find-file-noselect f))
|
||||
|
||||
;;;###autoload
|
||||
(defun bashdb (command-line)
|
||||
"Run bashdb on program FILE in buffer *gud-FILE*.
|
||||
The directory containing FILE becomes the initial working directory
|
||||
and source-file directory for your debugger."
|
||||
(interactive
|
||||
(if xemacsp
|
||||
(list (read-from-minibuffer "Run bashdb (like this): "
|
||||
(if (consp gud-bashdb-history)
|
||||
(car gud-bashdb-history)
|
||||
(format "%s " gud-bashdb-command-name))
|
||||
nil nil
|
||||
'(gud-bashdb-history . 1)))
|
||||
(list (gud-query-cmdline 'bashdb))
|
||||
))
|
||||
|
||||
(if xemacsp
|
||||
(progn
|
||||
(gud-overload-functions '((gud-massage-args . gud-bashdb-massage-args)
|
||||
(gud-marker-filter . gud-bashdb-marker-filter)
|
||||
(gud-find-file . gud-bashdb-find-file)))
|
||||
(gud-common-init command-line gud-bashdb-command-name))
|
||||
(gud-common-init command-line 'gud-bashdb-massage-args
|
||||
'gud-bashdb-marker-filter 'gud-bashdb-find-file)
|
||||
(set (make-local-variable 'gud-minor-mode) 'bashdb))
|
||||
|
||||
;; Unsupported commands
|
||||
;; condition foo set break condition to foo
|
||||
;; condition clear break condition
|
||||
;; display EXP evaluate and display EXP for each debug step
|
||||
;; display show a list of display expressions
|
||||
;; undisplay N remove display expression N
|
||||
;; ! string passes string to a shell
|
||||
;; quit quit
|
||||
|
||||
(gud-def gud-break "break %l" "\C-b" "Set breakpoint at current line.")
|
||||
(gud-def gud-list-break "break" "b" "List breakpoints & break condition.")
|
||||
(gud-def gud-remove "delete %l" "\C-d" "Remove breakpoint at current line")
|
||||
(gud-def gud-remove-all "delete" "d" "Clear all breakpoints")
|
||||
(gud-def gud-cont "continue" "\C-r" "Continue with display.")
|
||||
(gud-def gud-next "next" "\C-n" "Step one line (skip functions).")
|
||||
(gud-def gud-print "print %e" "\C-p" "Evaluate bash expression at point.")
|
||||
(gud-def gud-help "help" "h" "Show all commands.")
|
||||
(gud-def gud-trace "trace" "t" "Toggle execution trace on/off")
|
||||
|
||||
(setq comint-prompt-regexp "^bashdb> ")
|
||||
(setq paragraph-start comint-prompt-regexp)
|
||||
(run-hooks 'bashdb-mode-hook))
|
||||
|
||||
(provide 'bashdb)
|
||||
;; bashdb.el ends here
|
||||
|
|
@ -162,11 +162,11 @@ _declare_func()
|
|||
|
||||
COMPREPLY=()
|
||||
if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
|
||||
COMPREPLY=(-a -f -F -i -r -x -p)
|
||||
COMPREPLY=(-a -f -F -i -p -r -t -x)
|
||||
return 0;
|
||||
fi
|
||||
if [[ $cur == '+' ]]; then
|
||||
COMPREPLY=(+i +x)
|
||||
COMPREPLY=(+i +t +x)
|
||||
return 0;
|
||||
fi
|
||||
if [[ $prev == '-p' ]]; then
|
||||
|
|
@ -252,7 +252,7 @@ _hash_func()
|
|||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
|
||||
COMPREPLY=(-p -r)
|
||||
COMPREPLY=(-p -r -t)
|
||||
return 0;
|
||||
fi
|
||||
|
||||
|
|
@ -344,8 +344,8 @@ _complete_meta_func()
|
|||
|
||||
if (( $COMP_CWORD <= 1 )) || [[ "$cur" == '-' ]]; then
|
||||
case "$cmd" in
|
||||
complete) COMPREPLY=(-a -b -c -d -e -f -j -k -v -u -r -p -A -G -W -P -S -X -F -C);;
|
||||
compgen) COMPREPLY=(-a -b -c -d -e -f -j -k -v -u -A -G -W -P -S -X -F -C);;
|
||||
complete) COMPREPLY=(-a -b -c -d -e -f -j -k -s -v -u -r -p -A -G -W -P -S -X -F -C);;
|
||||
compgen) COMPREPLY=(-a -b -c -d -e -f -j -k -s -v -u -A -G -W -P -S -X -F -C);;
|
||||
esac
|
||||
return 0
|
||||
fi
|
||||
|
|
@ -353,7 +353,7 @@ _complete_meta_func()
|
|||
if [[ $prev == -A ]]; then
|
||||
COMPREPLY=(alias arrayvar binding builtin command directory \
|
||||
disabled enabled export file 'function' helptopic hostname job keyword \
|
||||
running setopt shopt signal stopped variable)
|
||||
running service setopt shopt signal stopped variable)
|
||||
return 0
|
||||
elif [[ $prev == -F ]]; then
|
||||
COMPREPLY=( $( compgen -A function $cur ) )
|
||||
|
|
@ -466,7 +466,7 @@ complete -f -X '*.bz2' bzip2
|
|||
complete -f -X '*.Z' compress
|
||||
complete -f -X '!*.+(gz|tgz|Gz)' gunzip gzcat zcat zmore
|
||||
complete -f -X '!*.Z' uncompress zmore zcat
|
||||
complete -f -X '!*.bz2' bunzip2
|
||||
complete -f -X '!*.bz2' bunzip2 bzcat
|
||||
complete -f -X '!*.zip' unzip
|
||||
complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|JPEG|bmp)' xv
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ hex2inet ()
|
|||
do
|
||||
case "$o" in
|
||||
r) rev=true;;
|
||||
*) echo "hex2inet: usage: hex2inet [0x]XXXXXXXX" >&2 ; exit 2;;
|
||||
*) echo "hex2inet: usage: hex2inet [-r] [0x]XXXXXXXX" >&2 ; exit 2;;
|
||||
esac
|
||||
done
|
||||
shift $(( $OPTIND - 1 ))
|
||||
|
|
|
|||
14
examples/functions/isvalidip
Normal file
14
examples/functions/isvalidip
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Thanks to Chris F. A. Johnson <c.f.a.johnson@rogers.com> for this one
|
||||
is_validip()
|
||||
{
|
||||
case "$*" in
|
||||
""|*[!0-9.]*|*[!0-9]) return 1 ;;
|
||||
esac
|
||||
|
||||
local IFS=.
|
||||
set -- $*
|
||||
|
||||
[ $# -eq 4 ] &&
|
||||
[ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
|
||||
[ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ function manpage ()
|
|||
set $file
|
||||
file="$1"
|
||||
if [ -f "$file" ]; then
|
||||
zot=$(head -1 "$file")
|
||||
zot=$(sed 1q "$file")
|
||||
cmd=${MANROFF:-"nroff -man - | col | cat -s"}
|
||||
h=${zot##"'"'\"'}
|
||||
if [ "$h" != "$zot" ]; then
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
mhfold()
|
||||
{
|
||||
list=`folders | tail +2 | awk '{print $1}'`
|
||||
list=`folders | awk '{if (1 < NR) print $1}'`
|
||||
/bin/ls -lag ~/Mail > /tmp/fold$$
|
||||
for i in $list; do
|
||||
grep $i /tmp/fold$$
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@ host_cpu = @host_cpu@
|
|||
host_vendor = @host_vendor@
|
||||
|
||||
CFLAGS = @CFLAGS@
|
||||
LOCAL_CFLAGS = @LOCAL_CFLAGS@
|
||||
DEFS = @DEFS@
|
||||
LOCAL_DEFS = @LOCAL_DEFS@
|
||||
|
||||
CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) $(CFLAGS)
|
||||
|
||||
#
|
||||
# These values are generated for configure by ${topdir}/support/shobj-conf.
|
||||
|
|
@ -62,7 +67,7 @@ INC = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(topdir)/builtins \
|
|||
-I$(BUILD_DIR)/builtins
|
||||
|
||||
.c.o:
|
||||
$(SHOBJ_CC) $(SHOBJ_CFLAGS) $(CFLAGS) $(INC) -c -o $@ $<
|
||||
$(SHOBJ_CC) $(SHOBJ_CFLAGS) $(CCFLAGS) $(INC) -c -o $@ $<
|
||||
|
||||
|
||||
ALLPROG = print truefalse sleep pushd finfo logname basename dirname \
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
* finfo - print file info
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "posixstat.h"
|
||||
#include <stdio.h>
|
||||
|
|
@ -127,10 +131,10 @@ char *f;
|
|||
{
|
||||
static struct stat st;
|
||||
int fd, r;
|
||||
long lfd;
|
||||
intmax_t lfd;
|
||||
|
||||
if (strncmp(f, "/dev/fd/", 8) == 0) {
|
||||
if (legal_number(f + 8, &lfd) == 0) {
|
||||
if ((legal_number(f + 8, &lfd) == 0) || (int)lfd != lfd) {
|
||||
builtin_error("%s: invalid fd", f + 8);
|
||||
return ((struct stat *)0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,19 @@
|
|||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include "typemax.h"
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "shell.h"
|
||||
#include "builtins.h"
|
||||
|
|
@ -857,7 +866,6 @@ static const struct conf_variable conf_table[] =
|
|||
static int num_getconf_variables = sizeof(conf_table) / sizeof(struct conf_variable) - 1;
|
||||
|
||||
extern char *this_command_name;
|
||||
extern char *xmalloc ();
|
||||
extern char **make_builtin_argv ();
|
||||
|
||||
static void getconf_help ();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
* print -- loadable ksh-93 style print builtin
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
|
@ -50,6 +54,7 @@ print_builtin (list)
|
|||
WORD_LIST *list;
|
||||
{
|
||||
int c, r, nflag, raw, ofd, sflag;
|
||||
intmax_t lfd;
|
||||
char **v, *pfmt, *arg;
|
||||
WORD_LIST *l;
|
||||
|
||||
|
|
@ -83,8 +88,8 @@ print_builtin (list)
|
|||
case 'p':
|
||||
break; /* NOP */
|
||||
case 'u':
|
||||
if (all_digits (list_optarg))
|
||||
ofd = atoi (list_optarg);
|
||||
if (all_digits (list_optarg) && legal_number (list_optarg, &lfd) && lfd == (int)lfd)
|
||||
ofd = lfd;
|
||||
else
|
||||
{
|
||||
for (l = list; l->next && l->next != lcurrent; l = l->next);
|
||||
|
|
|
|||
27
examples/obashdb/PERMISSION
Normal file
27
examples/obashdb/PERMISSION
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
From mikel@ora.com Tue Aug 1 12:13:20 1995
|
||||
Flags: 10
|
||||
Return-Path: mikel@ora.com
|
||||
Received: from ruby.ora.com (ruby.ora.com [198.112.208.25]) by odin.INS.CWRU.Edu with ESMTP (8.6.12+cwru/CWRU-2.1-ins)
|
||||
id MAA01565; Tue, 1 Aug 1995 12:13:18 -0400 (from mikel@ora.com for <chet@odin.INS.CWRU.Edu>)
|
||||
Received: (from fax@localhost) by ruby.ora.com (8.6.12/8.6.11) with UUCP id MAA23251; Tue, 1 Aug 1995 12:07:51 -0400
|
||||
Received: by los.ora.com (4.1/Spike-2.1)
|
||||
id AA00672; Tue, 1 Aug 95 08:57:32 EDT
|
||||
Date: Tue, 1 Aug 95 08:57:32 EDT
|
||||
From: mikel@ora.com (Michael Loukides)
|
||||
Message-Id: <9508011257.AA00672@los.ora.com>
|
||||
Subject: Re: Ksh debugger from Rosenblatt's book [for bash]
|
||||
To: Chet Ramey <chet@odin.INS.CWRU.Edu>
|
||||
Cc: cmarie@ora.com, cam@iinet.com.au, brosenblatt@tm.com
|
||||
In-Reply-To: Chet Ramey <chet@odin.INS.CWRU.Edu>, Mon, 31 Jul 1995 16:22:48 -0400
|
||||
|
||||
I've modified a (modified) version of Bill Rosenblatt's ksh debugger
|
||||
to work with bash-2.0. Does ORA have any problem with me distributing
|
||||
it with bash-2.0?
|
||||
|
||||
That's great!
|
||||
|
||||
Go ahead and circulate it; in fact, we should probably grab it and
|
||||
stick it in our ftp archive, and put a reference to it in the book.
|
||||
(Too late to actually discuss the thing, at least for this edition).
|
||||
-------
|
||||
|
||||
33
examples/obashdb/bashdb
Normal file
33
examples/obashdb/bashdb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# kshdb - Korn Shell Debugger main file
|
||||
# adapted from 'Learning the Korn Shell' by Bill Rosenblatt (O'Reilly)
|
||||
# by Cigy Cyriac (cigy@felix.tulblr.unisys.com)
|
||||
# Main driver: constructs full script (with preamble) and runs it
|
||||
|
||||
echo 'Bourne-Again Shell Debugger version 0.1'
|
||||
|
||||
_pname=${0##*/}
|
||||
|
||||
[ $# -eq 0 ] && {
|
||||
echo "${_pname}: usage: ${_pname} <script_file>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
_guineapig=$1
|
||||
|
||||
[ -r $_guineapig ] || {
|
||||
echo "${_pname}: cannot read $_guineapig." >&2
|
||||
exit 1
|
||||
}
|
||||
shift
|
||||
|
||||
_tmpdir=/tmp
|
||||
_libdir=.
|
||||
_dbgfile=$_tmpdir/bashdb$$ #temp file for script being debugged
|
||||
|
||||
cat $_libdir/bashdb.pre $_guineapig > $_dbgfile
|
||||
if [ -f "$BASH" ]; then
|
||||
exec $BASH $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
|
||||
else
|
||||
exec bash $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
|
||||
fi
|
||||
# end of bashdb
|
||||
|
|
@ -16,7 +16,7 @@ while :
|
|||
do
|
||||
$CLEAR
|
||||
echo "$HEADER"
|
||||
ps -aux | sort -nr +2 | sed ${SS}q
|
||||
ps -aux | sort -nr -k 3 | sed ${SS}q
|
||||
sleep 5
|
||||
done
|
||||
|
||||
|
|
|
|||
585
examples/scripts.v2/ren
Normal file
585
examples/scripts.v2/ren
Normal file
|
|
@ -0,0 +1,585 @@
|
|||
#!/bin/bash
|
||||
#@ This program came from: ftp://ftp.armory.com/pub/scripts/ren
|
||||
#@ Look there for the latest version.
|
||||
#@ If you don't find it, look through http://www.armory.com/~ftp/
|
||||
#
|
||||
# @(#) ren 2.1.1 2002-03-17
|
||||
# 1990-06-01 John H. DuBois III (john@armory.com)
|
||||
# 1991-02-25 Improved help info
|
||||
# 1992-06-07 Remove quotes from around shell pattern as required by new ksh
|
||||
# 1994-05-10 Exit if no globbing chars given.
|
||||
# 1995-01-23 Allow filename set to be given on command line.
|
||||
# 1997-09-24 1.4 Let [] be used for globbing. Added x option.
|
||||
# 1997-11-26 1.4.1 Notice if the sequences of globbing chars aren't the same.
|
||||
# 1999-05-13 Changed name to ren to avoid conflict with /etc/rename
|
||||
# 2000-01-01 1.4.2 Let input patterns that contain whitespace be used.
|
||||
# 2001-02-14 1.5 Better test for whether old & new globbing seqs are identical.
|
||||
# 2001-02-20 1.6 Added pP options.
|
||||
# 2001-02-27 1.7 Added qf options. Improved interpretation of rename patterns.
|
||||
# 2001-05-10 1.8 Allow multiple pP options. Added Qr options.
|
||||
# 2001-07-25 2.0 Added mz options.
|
||||
# 2001-11-25 2.1 Allow segment ranges to be given with -m. Work under ksh93.
|
||||
# 2002-03-17 2.1.1 Fixed bug in test for legal expressions.
|
||||
|
||||
# todo: It would be nice to be able to escape metacharacters with '\'
|
||||
# todo: Should enhance patterns to make ] in a pair of brackets work ([]])
|
||||
# todo: Allow use of all ksh globbing patterns.
|
||||
# todo: Allow use of extended regexps, with () to enumerate pieces and \num to
|
||||
# todo: select them.
|
||||
#
|
||||
# Modifications for bash made by Chet Ramey <chet@po.cwru.edu>
|
||||
|
||||
name=${0##*/}
|
||||
Usage="Usage:
|
||||
$name [-fhqtv] [-m<segstart[:segend]=operation>] [-z<len>] [-[pP]<pattern>]
|
||||
oldpattern [newpattern [filename ...]]
|
||||
or
|
||||
$name -r [same options as above] oldpattern newpattern directory ..."
|
||||
tell=false
|
||||
verbose=false
|
||||
warn=true
|
||||
warnNoFiles=true
|
||||
debug=false
|
||||
recurse=false
|
||||
inclPat=
|
||||
exclPat=
|
||||
declare -i inclCt=0 exclCt=0
|
||||
check=true
|
||||
declare -i j op_end_seg
|
||||
|
||||
# Begin bash additions
|
||||
shopt -s extglob
|
||||
|
||||
#
|
||||
# ksh print emulation
|
||||
#
|
||||
# print [-Rnprsu[n]] [-f format] [arg ...]
|
||||
#
|
||||
# - end of options
|
||||
# -R BSD-style -- only accept -n, no escapes
|
||||
# -n do not add trailing newline
|
||||
# -p no-op (no coprocesses)
|
||||
# -r no escapes
|
||||
# -s print to the history file
|
||||
# -u n redirect output to fd n
|
||||
# -f format printf "$format" "$@"
|
||||
#
|
||||
|
||||
print()
|
||||
{
|
||||
local eflag=-e
|
||||
local nflag= fflag= c
|
||||
local fd=1
|
||||
|
||||
OPTIND=1
|
||||
while getopts "fRnprsu:" c
|
||||
do
|
||||
case $c in
|
||||
R) eflag= ;;
|
||||
r) eflag= ;;
|
||||
n) nflag=-n ;;
|
||||
s) sflag=y ;;
|
||||
f) fflag=y ;;
|
||||
u) fd=$OPTARG ;;
|
||||
p) ;;
|
||||
esac
|
||||
done
|
||||
shift $(( $OPTIND - 1 ))
|
||||
|
||||
if [ -n "$fflag" ]; then
|
||||
builtin printf "$@" >&$fd
|
||||
return
|
||||
fi
|
||||
|
||||
case "$sflag" in
|
||||
y) builtin history -s "$*" ;;
|
||||
*) builtin echo $eflag $nflag "$@" >&$fd
|
||||
esac
|
||||
}
|
||||
|
||||
# End bash additions
|
||||
|
||||
while getopts :htvxp:P:fqQrm:z: opt; do
|
||||
case $opt in
|
||||
h)
|
||||
print -r -- \
|
||||
"$name: rename files by changing parts of filenames that match a pattern.
|
||||
$Usage
|
||||
oldpattern and newpattern are subsets of sh filename patterns; the only
|
||||
globbing operators (wildcards) allowed are ?, *, and []. All filenames that
|
||||
match oldpattern will be renamed with the filename characters that match the
|
||||
constant (non-globbing) characters of oldpattern changed to the corresponding
|
||||
constant characters of newpattern. The characters of the filename that match
|
||||
the globbing operators of oldpattern will be preserved. Globbing operators
|
||||
in oldpattern must occur in the same order in newpattern; for every globbing
|
||||
operators in newpattern there must be an identical globbing operators in
|
||||
oldpattern in the same sequence. Both arguments should be quoted since
|
||||
globbing operators are special to the shell. If filenames are given, only
|
||||
those named are acted on; if not, all filenames that match oldpattern are acted
|
||||
on. newpattern is required in all cases except when -m is given and no further
|
||||
arguments are given.
|
||||
If you are unsure whether a $name command will do what you intend, issue it
|
||||
with the -t option first to be sure.
|
||||
Examples:
|
||||
$name \"/tmp/foo*.ba.?\" \"/tmp/new*x?\"
|
||||
All filenames in /tmp that match foo*.ba.? will have the \"foo\" part
|
||||
replaced by \"new\" and the \".ba.\" part replaced by \"x\".
|
||||
For example, /tmp/fooblah.ba.baz would be renamed to /tmp/newblahxbaz.
|
||||
$name \* \*- foo bar baz
|
||||
foo, bar, and baz will be renamed to foo-, bar-, and baz-.
|
||||
$name '????????' '????-??-??'
|
||||
All filenames that are 8 characters long will be changed such that dashes
|
||||
are inserted after the 4th and 6th characters.
|
||||
Options:
|
||||
-h: Print this help.
|
||||
-r: Recursive operation. Filenames given on the command line after oldpattern
|
||||
and newpattern are taken to be directories to traverse recursively. For
|
||||
each subdirectory found, the specified renaming is applied to any matching
|
||||
filenames. oldpattern and newpattern should not include any directory
|
||||
components.
|
||||
-p<pattern>, -P<pattern>: Act only on filenames that do (if -p is given) or do
|
||||
not (if -P is given) match the sh-style filename globbing pattern
|
||||
<pattern>. This further restricts the filenames that are acted on, beyond
|
||||
the filename selection produced by oldpattern and the filename list (if
|
||||
any). <pattern> must be quoted to prevent it from being interpreted by the
|
||||
shell. Multiple instances of these options may be given. In this case,
|
||||
filenames are acted on only if they match at least one of the patterns
|
||||
given with -p and do not match any of the patterns given with -P.
|
||||
-m<segstart[:segend]=operation>: For each file being renamed, perform a
|
||||
mathematical operation on the string that results from concatenating
|
||||
together the filename segments that matched globbing operator numbers
|
||||
segstart through segend, where operators are numbered in order of
|
||||
occurrence from the left. For example, in the pattern a?b*c[0-9]f, segment
|
||||
1 consists of the character that matched ?, segment 2 consists of the
|
||||
character(s) that matched *, and segment 3 consists of the character that
|
||||
matched [0-9]. The selected segments are replaced with the result of the
|
||||
mathematical operation.
|
||||
The concatenated string must consist of characters that can be interpreted
|
||||
as a decimal integer; if it does not, the filename is not acted on. This
|
||||
number is assigned to the variable 'i', which can be referenced by the
|
||||
operation. The operations available are those understood by the ksh
|
||||
interpreter, which includes most of the operators and syntax of the C
|
||||
language. The original filename segment is replaced by the result of the
|
||||
operation. If -m is used, newpattern may be an empty string or not given
|
||||
at all (if no directory/file names are given). In this case, it is taken
|
||||
to be the same as oldpattern.
|
||||
If segend is given, any fixed text that occurs in the pattern between the
|
||||
starting and ending globbing segments is discarded. If there are fewer
|
||||
globbing segments than segend, no complaint is issued; the string is formed
|
||||
from segment segstart through the last segment that does exist.
|
||||
If segend is not given, the only segment acted on is startseg.
|
||||
Examples:
|
||||
$name -m3=i+6 '??*.ppm'
|
||||
This is equivalent to:
|
||||
$name -m3=i+6 '??*.ppm' '??*.ppm'
|
||||
Since the old pattern and new pattern are identical, this would
|
||||
normally be a no-op. But in this case, if a filename of ab079.ppm is
|
||||
given, it is changed to ab85.ppm.
|
||||
$name '-m1:2=i*2' 'foo??bar'
|
||||
This will change a file named foo12bar to foo24bar
|
||||
$name '-m1:2=i*2' 'foo?xyz?bar'
|
||||
This will also change a file named foo1xyz2bar to foo24bar
|
||||
-z<len>: Set the size of the number fields that result when -m is used. The
|
||||
field is truncated to the trailing <len> digits or filled out to <len>
|
||||
digits with leading zeroes. In the above example, if -z3 is given, the
|
||||
output filename will be ab085.ppm.
|
||||
-f: Force rename. By default, $name will not rename files if a file with the
|
||||
new filename already exists. If -f is given, $name will carry out the
|
||||
rename anyway.
|
||||
-q: Quiet operation. By default, if -f is given, $name will still notify the
|
||||
user if a rename results in replacement of an already-existing filename.
|
||||
If -q is given, no notification is issued.
|
||||
-Q: Suppress other warnings. By default, a warning is issued if no files are
|
||||
selected for acting upon. If -Q is given, no warning is issued.
|
||||
-v: Show the rename commands being executed.
|
||||
-t: Show what rename commands would be done, but do not carry them out."
|
||||
exit 0
|
||||
;;
|
||||
f)
|
||||
check=false
|
||||
;;
|
||||
q)
|
||||
warn=false
|
||||
;;
|
||||
Q)
|
||||
warnNoFiles=false
|
||||
;;
|
||||
r)
|
||||
warnNoFiles=false
|
||||
recurse=true
|
||||
;;
|
||||
t)
|
||||
tell=true
|
||||
;;
|
||||
v)
|
||||
verbose=true
|
||||
;;
|
||||
x)
|
||||
verbose=true
|
||||
debug=true
|
||||
;;
|
||||
p)
|
||||
inclPats[inclCt]=$OPTARG
|
||||
((inclCt+=1))
|
||||
;;
|
||||
P)
|
||||
exclPats[exclCt]=$OPTARG
|
||||
((exclCt+=1))
|
||||
;;
|
||||
m)
|
||||
# Store operation for each segment number in ops[num]
|
||||
# Store ending segment number in op_end_seg[num]
|
||||
range=${OPTARG%%=*}
|
||||
op=${OPTARG#*=}
|
||||
start=${range%%:*}
|
||||
end=${range#*:}
|
||||
if [[ "$start" != +([0-9]) || "$start" -eq 0 ]]; then
|
||||
print -ru2 -- "$name: Bad starting segment number given with -m: $start"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$end" != +([0-9]) || "$end" -eq 0 ]]; then
|
||||
print -ru2 -- "$name: Bad ending segment number given with -m: $end"
|
||||
exit 1
|
||||
fi
|
||||
if [[ start -gt end ]]; then
|
||||
print -ru2 -- "$name: Ending segment ($end) is less than starting segment ($start)"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$op" != @(|*[!_a-zA-Z0-9])i@(|[!_a-zA-Z0-9]*) ]]; then
|
||||
print -ru2 -- \
|
||||
"$name: Operation given with -m does not reference 'i': $op"
|
||||
exit 1
|
||||
fi
|
||||
# Test whether operation is legal. let returns 1 both for error
|
||||
# indication and when last expression evaluates to 0, so evaluate 1
|
||||
# after test expression.
|
||||
i=1
|
||||
let "$op" 1 2>/dev/null || {
|
||||
print -ru2 -- \
|
||||
"$name: Bad operation given with -m: $op"
|
||||
exit 1
|
||||
}
|
||||
ops[start]=$op
|
||||
op_end_seg[start]=$end
|
||||
;;
|
||||
z)
|
||||
if [[ "$OPTARG" != +([0-9]) || "$OPTARG" -eq 0 ]]; then
|
||||
print -ru2 -- "$name: Bad length given with -z: $OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
typeset -Z$OPTARG j || exit 1
|
||||
;;
|
||||
+?) # no way to tell getopts to not treat +x as an option
|
||||
print -r -u2 "$name: Do not prefix options with '+'."
|
||||
exit 1
|
||||
;;
|
||||
:)
|
||||
print -r -u2 \
|
||||
"$name: Option -$OPTARG requires a value.
|
||||
$Usage
|
||||
Use -h for help."
|
||||
exit 1
|
||||
;;
|
||||
\?)
|
||||
print -r -u2 \
|
||||
"$name: -$OPTARG: no such option.
|
||||
$Usage
|
||||
Use -h for help."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove args that were options
|
||||
let OPTIND=OPTIND-1
|
||||
shift $OPTIND
|
||||
|
||||
oldpat=$1
|
||||
newpat=$2
|
||||
|
||||
# If -m is given, a non-existant or null newpat should be set to oldpat
|
||||
if [ ${#ops[*]} -gt 0 ]; then
|
||||
case $# in
|
||||
0)
|
||||
;;
|
||||
1)
|
||||
set -- "$oldpat" "$oldpat"
|
||||
newpat=$oldpat
|
||||
$debug && print -ru2 -- "Set new pattern to: $newpat"
|
||||
;;
|
||||
*)
|
||||
if [ -z "$newpat" ]; then
|
||||
shift 2
|
||||
set -- "$oldpat" "$oldpat" "$@"
|
||||
newpat=$oldpat
|
||||
$debug && print -ru2 -- "Set new pattern to: $newpat"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Make sure input patterns that contain whitespace can be expanded properly
|
||||
IFS=
|
||||
|
||||
origPat=$oldpat
|
||||
|
||||
# Generate list of filenames to act on.
|
||||
case $# in
|
||||
[01])
|
||||
print -u2 "$Usage\nUse -h for help."
|
||||
exit 1
|
||||
;;
|
||||
2)
|
||||
if $recurse; then
|
||||
print -r -u2 "$name: No directory names given with -r. Use -h for help."
|
||||
exit 1
|
||||
fi
|
||||
set -- $oldpat # Get list of all filenames that match 1st globbing pattern.
|
||||
if [[ ! -a $1 ]]; then
|
||||
$warnNoFiles && print -r -- "$name: No filenames match this pattern: $oldpat"
|
||||
exit
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
shift 2
|
||||
;;
|
||||
esac
|
||||
|
||||
integer patSegNum=1 numPatSegs
|
||||
|
||||
# For old ksh
|
||||
# while [[ "$oldpat" = *'[\*\?]'* ]]; do
|
||||
|
||||
# Example oldpat: foo*.a
|
||||
# Example newpat: bar*.b
|
||||
|
||||
# Build list of non-pattern segments and globbing segments found in arguments.
|
||||
# Note the patterns given are used to get the list of filenames to act on,
|
||||
# to delimit constant segments, and to determine which parts of filenames are
|
||||
# to be replaced.
|
||||
# Examples given for first iteration (in the example, the only iteration)
|
||||
# The || newpat is to ensure that new pattern does not have more globbing
|
||||
# segments than old pattern
|
||||
while [[ "$oldpat" = *@([\*\?]|\[+([!\]])\])* ||
|
||||
"$newpat" = *@([\*\?]|\[+([!\]])\])* ]]; do
|
||||
## Get leftmost globbing pattern in oldpat
|
||||
|
||||
# Make r be oldpat with smallest left piece that includes a globbing
|
||||
# pattern removed from it
|
||||
r=${oldpat#*@([\*\?]|\[+([!\]])\])} # r=.a
|
||||
# Make pat be oldpat with the above removed from it, leaving smallest
|
||||
# left piece that includes a globbing pattern
|
||||
pat=${oldpat%%"$r"} # pat=foo*
|
||||
# Make l be pat with the globbing pattern removed from the right,
|
||||
# leaving a constant string
|
||||
l=${pat%@([\*\?]|\[+([!\]])\])} # l=foo
|
||||
# Remove the constant part of pat from the left, leaving the globbing
|
||||
# pattern
|
||||
pat=${pat#"$l"} # pat=*
|
||||
|
||||
# Do the same thing for newpat, solely to provide a reliable test that
|
||||
# both oldpat & newpat contain exactly the same sequence of globbing
|
||||
# patterns.
|
||||
r=${newpat#*@([\*\?]|\[+([!\]])\])} # r=.b
|
||||
npat=${newpat%%"$r"} # pat=bar*
|
||||
l=${npat%@([\*\?]|\[+([!\]])\])} # l=bar
|
||||
npat=${npat#"$l"} # npat=*
|
||||
|
||||
if [[ "$pat" != "$npat" ]]; then
|
||||
print -ru2 -- \
|
||||
"$name: Old-pattern and new-pattern do not have the same sequence of globbing chars.
|
||||
Pattern segment $patSegNum: Old pattern: $pat New pattern: $npat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Find parts before & after pattern
|
||||
# oldpre[] stores the old constant part before the pattern,
|
||||
# so that it can be removed and replaced with the new constant part.
|
||||
oldpre[patSegNum]=${oldpat%%"$pat"*} # oldpre[1]=foo
|
||||
# oldsuf stores the part that follows the globbing pattern,
|
||||
# so that it too can be removed.
|
||||
# After oldpre[] & oldsuf[] have been removed from a filename, what remains
|
||||
# is the part matched by the globbing pattern, which is to be retained.
|
||||
oldsuf[patSegNum]=${oldpat#*"$pat"} # oldsuf[1]=.a
|
||||
# newpre[] stores the new constant part before the pattern,
|
||||
# so that it can be used to replace the old constant part.
|
||||
newpre[patSegNum]=${newpat%%"$pat"*} # newpre[1]=bar
|
||||
# Get rid of processed part of patterns
|
||||
oldpat=${oldpat#${oldpre[patSegNum]}"$pat"} # oldpat=.a
|
||||
newpat=${newpat#${newpre[patSegNum]}"$pat"} # newpat=.b
|
||||
# Store either * or ? in pats[], depending on whether this segment matches 1
|
||||
# or any number of characters.
|
||||
[[ "$pat" = \[* ]] && pat=?
|
||||
pats[patSegNum]=$pat
|
||||
((patSegNum+=1))
|
||||
done
|
||||
|
||||
if [ patSegNum -eq 1 ]; then
|
||||
print -u2 "No globbing chars in pattern."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
oldpre[patSegNum]=${oldpat%%"$pat"*} # oldpre[2]=.a
|
||||
oldsuf[patSegNum]=${oldpat#*"$pat"} # oldsuf[2]=.a
|
||||
newpre[patSegNum]=${newpat%%"$pat"*} # newpre[2]=.b
|
||||
|
||||
numPatSegs=patSegNum
|
||||
|
||||
if $debug; then
|
||||
patSegNum=1
|
||||
while [[ patSegNum -le numPatSegs ]]; do
|
||||
print -ru2 -- \
|
||||
"Old prefix: <${oldpre[patSegNum]}> Old suffix: <${oldsuf[patSegNum]}> New prefix: <${newpre[patSegNum]}> Pattern: <${pats[patSegNum]}>"
|
||||
((patSegNum+=1))
|
||||
done
|
||||
fi
|
||||
|
||||
# Example filename: foox.a
|
||||
# Example oldpat: foo*.a
|
||||
# Example newpat: bar*.b
|
||||
|
||||
integer numFiles=0
|
||||
|
||||
# Usage: renameFile filename [dirname]
|
||||
# [dirname] is a directory name to prefix filenames with when they are printed
|
||||
# for informational purposes.
|
||||
# Uses globals:
|
||||
# inclCt exclCt inclPats[] exclPats[] ops[]
|
||||
# numPatSegs oldpre[] oldsuf[] newpre[] pats[]
|
||||
# check warn tell verbose name
|
||||
# Modifies globals: numFiles
|
||||
function renameFile {
|
||||
typeset file=$1 subdir=$2
|
||||
integer patSegNum patnum
|
||||
typeset origname porigname newfile matchtext pnewfile matchsegs
|
||||
integer startseg endseg
|
||||
|
||||
origname=$file # origname=foox.a
|
||||
porigname=$subdir$file
|
||||
# Unfortunately, ksh88 does not do a good job of allowing for patterns
|
||||
# stored in variables. Without the conditional expression being eval'ed,
|
||||
# only sh patterns are recognized. If the expression is eval'ed, full
|
||||
# ksh expressions can be used, but then expressions that contain whitespace
|
||||
# break unless the user passed a pattern with the whitespace properly
|
||||
# quoted, which is not intuititive. This is fixed in ksh93; full patterns
|
||||
# work without being eval'ed.
|
||||
if [ inclCt -gt 0 ]; then
|
||||
patnum=0
|
||||
while [ patnum -lt inclCt ]; do
|
||||
[[ "$file" = ${inclPats[patnum]} ]] && break
|
||||
((patnum+=1))
|
||||
done
|
||||
if [ patnum -eq inclCt ]; then
|
||||
$debug && print -ru2 -- "Skipping not-included filename '$porigname'"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
patnum=0
|
||||
while [ patnum -lt exclCt ]; do
|
||||
if [[ "$file" = ${exclPats[patnum]} ]]; then
|
||||
$debug && print -ru2 -- "Skipping excluded filename '$porigname'"
|
||||
return 1
|
||||
fi
|
||||
((patnum+=1))
|
||||
done
|
||||
# Extract matching segments from filename
|
||||
((numFiles+=1))
|
||||
patSegNum=1
|
||||
while [[ patSegNum -le numPatSegs ]]; do
|
||||
# Remove a fixed prefix iteration: 1 2
|
||||
file=${file#${oldpre[patSegNum]}} # file=x.a file=
|
||||
# Save the part of this suffix that is to be retained. To do this, we
|
||||
# need to know what part of the suffix matched the current globbing
|
||||
# segment. If the globbing segment is a *, this is done by removing
|
||||
# the minimum part of the suffix that matches oldsuf (since * matches
|
||||
# the longest segment possible). If the globbing segment is ? or []
|
||||
# (the latter has already been coverted to ?), it is done by taking the
|
||||
# next character.
|
||||
if [ "${pats[patSegNum]}" == \? ]; then
|
||||
matchtext=${file#?}
|
||||
matchtext=${file%$matchtext}
|
||||
else
|
||||
matchtext=${file%${oldsuf[patSegNum]}} # matchtext=x matchtext=
|
||||
fi
|
||||
$debug && print -ru2 -- "Matching segment $patSegNum: $matchtext"
|
||||
file=${file#$matchtext} # file=.a file=.a
|
||||
|
||||
matchsegs[patSegNum]=$matchtext
|
||||
((patSegNum+=1))
|
||||
done
|
||||
|
||||
# Paste fixed and matching segments together to form new filename.
|
||||
patSegNum=0
|
||||
newfile=
|
||||
while [[ patSegNum -le numPatSegs ]]; do
|
||||
matchtext=${matchsegs[patSegNum]}
|
||||
startseg=patSegNum
|
||||
if [ -n "${ops[startseg]}" ]; then
|
||||
endseg=${op_end_seg[startseg]}
|
||||
while [ patSegNum -lt endseg ]; do
|
||||
((patSegNum+=1))
|
||||
matchtext=$matchtext${matchsegs[patSegNum]}
|
||||
done
|
||||
if [[ "$matchtext" != +([-0-9]) ]]; then
|
||||
print -ru2 -- \
|
||||
"Segment(s) $startseg - $endseg ($matchtext) of file '$porigname' do not form an integer; skipping this file."
|
||||
return 2
|
||||
fi
|
||||
i=$matchtext
|
||||
let "j=${ops[startseg]}" || {
|
||||
print -ru2 -- \
|
||||
"Operation failed on segment(s) $startseg - $endseg ($matchtext) of file '$file'; skipping this file."
|
||||
return 2
|
||||
}
|
||||
$debug && print -ru2 -- "Converted $matchtext to $j"
|
||||
matchtext=$j
|
||||
fi
|
||||
newfile=$newfile${newpre[startseg]}$matchtext # newfile=barx newfile=barx.b
|
||||
((patSegNum+=1))
|
||||
done
|
||||
|
||||
pnewfile=$subdir$newfile
|
||||
if $check && [ -e "$newfile" ]; then
|
||||
$warn &&
|
||||
print -ru2 -- "$name: Not renaming \"$porigname\"; destination filename \"$pnewfile\" already exists."
|
||||
return 2
|
||||
fi
|
||||
if $tell; then
|
||||
print -n -r -- "Would move: $porigname -> $pnewfile"
|
||||
$warn && [ -e "$newfile" ] && print -n -r " (destination filename already exists; would replace it)"
|
||||
print ""
|
||||
else
|
||||
if $verbose; then
|
||||
print -n -r -- "Moving: $porigname -> $pnewfile"
|
||||
$warn && [ -e "$newfile" ] && print -n -r -- " (replacing old destination filename \"$pnewfile\")"
|
||||
print ""
|
||||
elif $warn && [ -e "$newfile" ]; then
|
||||
print -r -- "$name: Note: Replacing old file \"$pnewfile\""
|
||||
fi
|
||||
mv -f -- "$origname" "$newfile"
|
||||
fi
|
||||
}
|
||||
|
||||
if $recurse; then
|
||||
oPWD=$PWD
|
||||
find "$@" -depth -type d ! -name '*
|
||||
*' -print | while read dir; do
|
||||
cd -- "$oPWD"
|
||||
if cd -- "$dir"; then
|
||||
for file in $origPat; do
|
||||
renameFile "$file" "$dir/"
|
||||
done
|
||||
else
|
||||
print -ru2 -- "$name: Could not access directory '$dir' - skipped."
|
||||
fi
|
||||
done
|
||||
else
|
||||
for file; do
|
||||
renameFile "$file"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ numFiles -eq 0 ]; then
|
||||
$warnNoFiles && print -ru2 -- \
|
||||
"$name: All filenames were excluded by patterns given with -p or -P."
|
||||
fi
|
||||
|
|
@ -335,7 +335,7 @@ if test -s "$histfile"
|
|||
then
|
||||
cmdno="`set - \`wc -l $histfile\`;echo $1`"
|
||||
cmdno="`expr \"$cmdno\" + 1`"
|
||||
lastcmd="`tail -1 $histfile`"
|
||||
lastcmd="`sed -n '$p' $histfile`"
|
||||
copy=false
|
||||
ohist=$histfile
|
||||
while test ! -w "$histfile"
|
||||
|
|
@ -689,7 +689,7 @@ esac/
|
|||
rest=
|
||||
;;
|
||||
esac
|
||||
i="`grep \"$wanted\" $histfile | tail -1`"
|
||||
i="`grep \"$wanted\" $histfile | sed -n '$p'`"
|
||||
;;
|
||||
*)
|
||||
# find which 'start-of-command' match is wanted
|
||||
|
|
@ -708,7 +708,7 @@ esac/
|
|||
rest=
|
||||
;;
|
||||
esac
|
||||
i="`grep \"^$wanted\" $histfile | tail -1`"
|
||||
i="`grep \"^$wanted\" $histfile | sed -n '$p'`"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
|||
9
examples/scripts/self-repro
Normal file
9
examples/scripts/self-repro
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# self-reproducing script (except for these comment lines -- remove them)
|
||||
# i got this from the ksh93 faq:
|
||||
# http://www.kornshell.com/doc/faq.html
|
||||
#
|
||||
n="
|
||||
" q="'" x="cat <<-!" y=! z='n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y'
|
||||
cat <<-!
|
||||
n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$yb
|
||||
!
|
||||
|
|
@ -32,7 +32,7 @@ do
|
|||
cd "$1" || { shift; [ $# -ge 1 ] && echo >&2; continue; }
|
||||
echo -n "$PWD"
|
||||
|
||||
du $andfiles | sort +1f | sed \
|
||||
du $andfiles | sort -k 2f | sed \
|
||||
-e 's/\([^ ]*\) \(.*\)/\2 (\1)/' \
|
||||
-e "s#^$1##" \
|
||||
-e 's#[^/]*/\([^/]*\)$#|____\1#' \
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ ff () { find . -name ${1} -print ; }
|
|||
ll () { ls -lag "$@" | more ; }
|
||||
word () { fgrep -i "$*" /usr/dict/web2 ; }
|
||||
wordcount () { cat "${1}" | tr -s ' .,;:?\!()[]"' '\012' | \
|
||||
cat -n | tail -1 | awk '{print $1}' ; }
|
||||
awk 'END {print NR}' ; }
|
||||
|
||||
##
|
||||
# Read user's aliases
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue