Friday, 27 January 2012

clearing selective history in centos multiple lines script

# This bash script must be used with 'source' or '.'
# and so it does not need to be made executable.
# . scriptname          Display last 35 history lines (default)
# . scriptname n        Display last n history lines
# The lines are displayed with their line numbers.
# Enter a list of the lines to be deleted
# An example of a line list is 90 45-56 78-
# 90     Delete line 90
# 45-56  Delete lines 45 to 56 (can also use 56-45)
# 78-    Delete line 78 to the last line
# Number ranges can be in any order in the list and can overlap.
# The lines are deleted in memory, not from the history file.

displaylines=35  # default
#displaylines=    # if unset all of the history will be displayed
if [ "$1" ];then displaylines=$1;fi # or use $1 instead of default

lastline=$(echo $(history 1))   # Last line, with leading spaces removed
lastlinenum=${lastline%%[* ]*}  # Extract line number from the last line
# Note: '*' after a line number in bash history indicates a modified line

# history -d$lastlinenum # Delete the command which ran this script (optional)
history $displaylines   # Display history
while true;do
  if [ "${displaylines//[0-9]/}" ];then break;fi # If it contains non-integer characters.
  read -ep "Lines to delete (e.g. 67-89 45 103- ) or enter nothing to quit: " numbers
  if ! [ "$numbers" ];then break;fi     # exit if nothing entered
  numbers="$numbers "                   # Append a space to the line number list
  numbers=${numbers//- /-$lastlinenum } # e.g change '23- ' to '23-lastlinenumber '
  numbers=$(echo $numbers)              # Remove unnecessary spaces

  # Check the entered number list is valid:
  errors=$(echo "${numbers// /
}"|while read line;do
   # [ "not just digits and -" OR "more than one -" OR "starts with -" ] && echo 'error'
     [  "${line//[0-9-]/}" -o  "${line%%*-*-*}" = '' -o "${line:0:1}" = '-' ] && echo 'error'
  if [ "$errors"  ];then echo "Bad line number list, try again:";continue;fi

  # Expand line ranges n-m to a list of individual line numbers
  numbers=$(echo "${numbers// /
}" | while read line;do
       if [ "${line#*-}" != "$line" ];then # Found a line containing '-'  (a range 'n-m')
         if [ $n -lt $m ];then line="$m-$n";fi # Descending order for faster reverse sorting
         line="{${line/-/..}}"  # Change 'n-m' to '{n..m}'
       eval echo $line  # '{n..m}' will be expanded to a list of numbers (brace expansion)
  a=( $numbers ) # Put line numbers into an array for reverse unique sorting
  while [ "$sorted" = "no" ];do
    unset sorted
    for ((i=0;i<${#a[@]}-1;i++));do
      if (( ${a[i]} < ${a[i+1]} ));then  # Sort by comparing/swapping adjacent elements
  for ((i=0;i<${#a[@]}-1;i++));do # Remove duplicate line numbers from the sorted array
    if (( ${a[i]} == ${a[i+1]} ));then
  a=( ${a[@]} ) # Remove empty array elements created by removing duplicates
  i=${#a[@]}    # Number of array elements
  # Check that the reverse sorted list is in the range  $lastlinenum to 1
  if [ ${a[0]} -gt $lastlinenum -o ${a[i-1]} -lt 1 ];then
    echo "Line number list is out of range, try again:"
  echo "Deleting these lines from the above history: ${a[@]}"
  echo "***********************************************************************"
  for ((i=0;i<${#a[@]};i++));do
    a[i]="history -d${a[i]};"  # Create the delete commands e.g. history -d67; ....
  eval ${a[@]}                     # Execute all the 'history -d' commands
  lastline=$(echo $(history 1))    # New last line, with leading spaces removed
  lastlinenum=${lastline%%[* ]*}   # Extract the line number from the new last line
  history $displaylines            # Refresh the displayed history
unset a errors i lastline lastlinenum line numbers sorted tmp # Finished; tidy up

No comments:

Post a Comment

Twitter Bird Gadget