General tidy
This commit is contained in:
parent
569bd7ada5
commit
0a83ba9952
|
@ -1,6 +1,5 @@
|
|||
# Lots of junk goes in here.
|
||||
/caches/
|
||||
/backups/
|
||||
|
||||
# Top secret stuff!
|
||||
/link/.ssh/authorized_keys
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
HOST="inspiron"
|
||||
DEST="de1103@de1103.rsync.net:borg_${HOST}"
|
||||
SOURCES="/home /data/Shared/Shared_Documents /data/Shared/Shared_Software"
|
||||
SOURCES=("/home" "/data/Shared/Shared_Documents" "/data/Shared/Shared_Software")
|
||||
|
||||
if [ $(hostname -s) != "${HOST}" ]; then
|
||||
if [ "$(hostname -s)" != "${HOST}" ]; then
|
||||
echo "Must be run from ${HOST}"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
echo "Backup to ${DEST}"
|
||||
sudo borg create --remote-path=borg1 -s --progress "${DEST}::$(date '+%Y%m%d-%H%M')" ${SOURCES}
|
||||
sudo borg create --remote-path=borg1 -s --progress "${DEST}::$(date '+%Y%m%d-%H%M')" "${SOURCES[@]}"
|
||||
|
||||
echo
|
||||
echo DONE
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
HOST="LEGION"
|
||||
DEST="dctrud@piran:/usb/borg/borg_${HOST}"
|
||||
SOURCES="/home /mnt/d/Ben /mnt/d/Dave /mnt/d/Dona /mnt/d/Shared /mnt/d/Thomas"
|
||||
SOURCES=("/home" "/mnt/d/Ben" "/mnt/d/Dave" "/mnt/d/Dona" "/mnt/d/Shared" "/mnt/d/Thomas")
|
||||
|
||||
if [ $(hostname -s) != "${HOST}" ]; then
|
||||
if [ "$(hostname -s)" != "${HOST}" ]; then
|
||||
echo "Must be run from ${HOST}"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
echo "Backup to ${DEST}"
|
||||
sudo borg create -s --progress "${DEST}::$(date '+%Y%m%d-%H%M')" ${SOURCES}
|
||||
sudo borg create -s --progress "${DEST}::$(date '+%Y%m%d-%H%M')" "${SOURCES[@]}"
|
||||
|
||||
echo
|
||||
echo DONE
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
HOST="mini"
|
||||
DEST="dctrud@piran:/usb/borg/borg_${HOST}"
|
||||
SOURCES="/home /etc /var /data"
|
||||
SOURCES=("/home" "/etc" "/var" /"data")
|
||||
|
||||
if [ $(hostname -s) != "${HOST}" ]; then
|
||||
if [ "$(hostname -s)" != "${HOST}" ]; then
|
||||
echo "Must be run from ${HOST}"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
echo "Backup to ${DEST}"
|
||||
sudo borg create -s --progress "${DEST}::$(date '+%Y%m%d-%H%M')" ${SOURCES}
|
||||
sudo borg create -s --progress "${DEST}::$(date '+%Y%m%d-%H%M')" "${SOURCES[@]}"
|
||||
|
||||
echo
|
||||
echo DONE
|
||||
|
|
198
bin/dotfiles
198
bin/dotfiles
|
@ -1,7 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
[[ "$1" == "source" ]] || \
|
||||
|
||||
echo 'Dotfiles - "Cowboy" Ben Alman - http://benalman.com/'
|
||||
if [[ "$1" != "source" ]]; then
|
||||
echo "dctrud's dotfiles"
|
||||
echo
|
||||
echo "Adapted from:"
|
||||
echo ' Dotfiles - "Cowboy" Ben Alman - http://benalman.com/'
|
||||
fi
|
||||
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then cat <<HELP
|
||||
|
||||
|
@ -24,10 +27,10 @@ exit; fi
|
|||
export DOTFILES=~/.dotfiles
|
||||
|
||||
# Logging stuff.
|
||||
function e_header() { echo -e "\n\033[1m$@\033[0m"; }
|
||||
function e_success() { echo -e " \033[1;32m✔\033[0m $@"; }
|
||||
function e_error() { echo -e " \033[1;31m✖\033[0m $@"; }
|
||||
function e_arrow() { echo -e " \033[1;34m➜\033[0m $@"; }
|
||||
function e_header() { echo -e "\n\033[1m$*\033[0m"; }
|
||||
function e_success() { echo -e " \033[1;32m✔\033[0m $*"; }
|
||||
function e_error() { echo -e " \033[1;31m✖\033[0m $*"; }
|
||||
function e_arrow() { echo -e " \033[1;34m➜\033[0m $*"; }
|
||||
|
||||
# For testing some of these functions.
|
||||
function assert() {
|
||||
|
@ -56,22 +59,19 @@ function is_dotfiles_running() {
|
|||
|
||||
# Test if this script was run via the "dotfiles" bin script (vs. via curl/wget)
|
||||
function is_dotfiles_bin() {
|
||||
[[ "$(basename $0 2>/dev/null)" == dotfiles ]] || return 1
|
||||
[[ $(basename "$0" 2>/dev/null) == dotfiles ]] || return 1
|
||||
}
|
||||
|
||||
# OS detection
|
||||
function is_linux() {
|
||||
[[ "$OSTYPE" =~ ^linux ]] || return 1
|
||||
}
|
||||
function is_osx() {
|
||||
[[ "$OSTYPE" =~ ^darwin ]] || return 1
|
||||
}
|
||||
function is_ubuntu() {
|
||||
[[ "$(cat /etc/issue 2> /dev/null)" =~ Ubuntu ]] || return 1
|
||||
}
|
||||
function is_ubuntu_desktop() {
|
||||
dpkg -l ubuntu-desktop >/dev/null 2>&1 || return 1
|
||||
}
|
||||
function get_os() {
|
||||
for os in osx ubuntu ubuntu_desktop; do
|
||||
is_$os; [[ $? == ${1:-0} ]] && echo $os
|
||||
for os in linux osx; do
|
||||
is_$os; [[ $? == "${1:-0}" ]] && echo $os
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -89,18 +89,18 @@ function path_remove() {
|
|||
# Display a fancy multi-select menu.
|
||||
# Inspired by http://serverfault.com/a/298312
|
||||
function prompt_menu() {
|
||||
local exitcode prompt choices nums i n
|
||||
local exitcode prompt nums i n
|
||||
exitcode=0
|
||||
if [[ "$2" ]]; then
|
||||
_prompt_menu_draws "$1"
|
||||
read -t $2 -n 1 -sp "Press ENTER or wait $2 seconds to continue, or press any other key to edit."
|
||||
read -r -t "$2" -n 1 -sp "Press ENTER or wait $2 seconds to continue, or press any other key to edit."
|
||||
exitcode=$?
|
||||
echo ""
|
||||
fi 1>&2
|
||||
if [[ "$exitcode" == 0 && "$REPLY" ]]; then
|
||||
prompt="Toggle options (Separate options with spaces, ENTER when done): "
|
||||
while _prompt_menu_draws "$1" 1 && read -rp "$prompt" nums && [[ "$nums" ]]; do
|
||||
_prompt_menu_adds $nums
|
||||
_prompt_menu_adds "$nums"
|
||||
done
|
||||
fi 1>&2
|
||||
_prompt_menu_adds
|
||||
|
@ -114,7 +114,7 @@ function _prompt_menu_iter() {
|
|||
for sel in "${menu_selects[@]}"; do
|
||||
[[ "$sel" == "${menu_options[i]}" ]] && state=1 && break
|
||||
done
|
||||
$fn $state $i "$@"
|
||||
$fn $state "$i" "$@"
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -126,9 +126,9 @@ function _prompt_menu_draws() {
|
|||
function _prompt_menu_draw() {
|
||||
local modes=(error success)
|
||||
if [[ "$3" ]]; then
|
||||
e_${modes[$1]} "$(printf "%2d) %s\n" $(($2+1)) "${menu_options[$2]}")"
|
||||
e_"${modes[$1]}" "$(printf "%2d) %s\n" $(($2+1)) "${menu_options[$2]}")"
|
||||
else
|
||||
e_${modes[$1]} "${menu_options[$2]}"
|
||||
e_"${modes[$1]}" "${menu_options[$2]}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -157,10 +157,10 @@ function _prompt_menu_add() {
|
|||
# Usage: array_map array_name [map_fn]
|
||||
function array_map() {
|
||||
local __i__ __val__ __arr__=$1; shift
|
||||
for __i__ in $(eval echo "\${!$__arr__[@]}"); do
|
||||
__val__="$(eval echo "\"\${$__arr__[__i__]}\"")"
|
||||
for __i__ in $(eval echo "\${!${__arr__[*]}}"); do
|
||||
__val__="$(eval echo "\"\${${__arr__[__i__]}}\"")"
|
||||
if [[ "$1" ]]; then
|
||||
"$@" "$__val__" $__i__
|
||||
"$@" "$__val__" "$__i__"
|
||||
else
|
||||
echo "$__val__"
|
||||
fi
|
||||
|
@ -168,7 +168,7 @@ function array_map() {
|
|||
}
|
||||
|
||||
# Print bash array in the format "i <val>" (one per line) for debugging.
|
||||
function array_print() { array_map $1 __array_print; }
|
||||
function array_print() { array_map "$1" __array_print; }
|
||||
function __array_print() { echo "$2 <$1>"; }
|
||||
|
||||
# Array filter. Calls filter_fn for each item ($1) and index ($2) in array_name
|
||||
|
@ -184,18 +184,18 @@ function array_filter_i() { __array_filter 0 "$@"; }
|
|||
function __array_filter() {
|
||||
local __i__ __val__ __mode__ __arr__
|
||||
__mode__=$1; shift; __arr__=$1; shift
|
||||
for __i__ in $(eval echo "\${!$__arr__[@]}"); do
|
||||
__val__="$(eval echo "\${$__arr__[__i__]}")"
|
||||
for __i__ in $(eval echo "\${!${__arr__[*]}}"); do
|
||||
__val__="$(eval echo "\${${__arr__[__i__]}}")"
|
||||
if [[ "$1" ]]; then
|
||||
"$@" "$__val__" $__i__ >/dev/null
|
||||
"$@" "$__val__" "$__i__" >/dev/null
|
||||
else
|
||||
[[ "$__val__" ]]
|
||||
fi
|
||||
if [[ "$?" == 0 ]]; then
|
||||
if [[ $__mode__ == 1 ]]; then
|
||||
eval echo "\"\${$__arr__[__i__]}\""
|
||||
eval echo "\"\${${__arr__[__i__]}}\""
|
||||
else
|
||||
echo $__i__
|
||||
echo "$__i__"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
@ -209,10 +209,10 @@ function array_join_filter() { __array_join 0 "$@"; }
|
|||
function __array_join() {
|
||||
local __i__ __val__ __out__ __init__ __mode__ __arr__
|
||||
__mode__=$1; shift; __arr__=$1; shift
|
||||
for __i__ in $(eval echo "\${!$__arr__[@]}"); do
|
||||
__val__="$(eval echo "\"\${$__arr__[__i__]}\"")"
|
||||
for __i__ in $(eval echo "\${!${__arr__[*]}}"); do
|
||||
__val__="$(eval echo "\"\${${__arr__[__i__]}}\"")"
|
||||
if [[ $__mode__ == 1 || "$__val__" ]]; then
|
||||
[[ "$__init__" ]] && __out__="$__out__$@"
|
||||
[[ "$__init__" ]] && __out__="$__out__$*"
|
||||
__out__="$__out__$__val__"
|
||||
__init__=1
|
||||
fi
|
||||
|
@ -241,7 +241,7 @@ function setdiff() {
|
|||
if [[ "$1" == 1 ]]; then debug=1; shift; fi
|
||||
if [[ "$1" ]]; then
|
||||
local setdiff_new setdiff_cur setdiff_out
|
||||
setdiff_new=($1); setdiff_cur=($2)
|
||||
setdiff_new=("$1"); setdiff_cur=("$2")
|
||||
fi
|
||||
setdiff_out=()
|
||||
for a in "${setdiff_new[@]}"; do
|
||||
|
@ -252,7 +252,7 @@ function setdiff() {
|
|||
[[ "$skip" ]] || setdiff_out=("${setdiff_out[@]}" "$a")
|
||||
done
|
||||
[[ "$debug" ]] && for a in setdiff_new setdiff_cur setdiff_out; do
|
||||
echo "$a ($(eval echo "\${#$a[*]}")) $(eval echo "\${$a[*]}")" 1>&2
|
||||
echo "$a ($(eval echo "\${#${a[*]}}")) $(eval echo "\${${a[*]}}")" 1>&2
|
||||
done
|
||||
[[ "$1" ]] && echo "${setdiff_out[@]}"
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ function init_files() {
|
|||
[[ "$remove" ]] || menu_selects=("${menu_selects[@]}" "$opt")
|
||||
done
|
||||
fi
|
||||
prompt_menu "Run the following init scripts?" $prompt_delay
|
||||
prompt_menu "Run the following init scripts?" "$prompt_delay"
|
||||
# Write out cache file for future reading.
|
||||
rm "$init_file" 2>/dev/null
|
||||
for i in "${!menu_selects[@]}"; do
|
||||
|
@ -327,7 +327,7 @@ function link_test() {
|
|||
}
|
||||
function link_do() {
|
||||
e_success "Linking ~/$1."
|
||||
ln -sf ${2#$HOME/} ~/
|
||||
ln -sf "${2#"$HOME"/}" ~/
|
||||
}
|
||||
|
||||
# Link config files.
|
||||
|
@ -340,21 +340,21 @@ function config_test() {
|
|||
}
|
||||
function config_do() {
|
||||
e_success "Linking ~/.config/$1."
|
||||
ln -sf ../${2#$HOME/} ~/.config/
|
||||
ln -sf ../"${2#"$HOME"/}" ~/.config/
|
||||
}
|
||||
|
||||
# Copy, link, init, etc.
|
||||
function do_stuff() {
|
||||
local base dest skip
|
||||
local files=($DOTFILES/$1/*)
|
||||
[[ $(declare -f "$1_files") ]] && files=($($1_files "${files[@]}"))
|
||||
local files=("$DOTFILES"/"$1"/*)
|
||||
[[ $(declare -f "$1_files") ]] && files=($("$1_files" "${files[@]}"))
|
||||
# No files? abort.
|
||||
if (( ${#files[@]} == 0 )); then return; fi
|
||||
# Run _header function only if declared.
|
||||
[[ $(declare -f "$1_header") ]] && "$1_header"
|
||||
# Iterate over files.
|
||||
for file in "${files[@]}"; do
|
||||
base="$(basename $file)"
|
||||
base="$(basename "$file")"
|
||||
# Get dest path.
|
||||
if [[ $(declare -f "$1_dest") ]]; then
|
||||
dest="$("$1_dest" "$base")"
|
||||
|
@ -369,16 +369,6 @@ function do_stuff() {
|
|||
e_error "Skipping ~/$base, $skip."
|
||||
continue
|
||||
fi
|
||||
# Destination file already exists in ~/. Back it up!
|
||||
if [[ -e "$dest" ]]; then
|
||||
e_arrow "Backing up ~/$base."
|
||||
# Set backup flag, so a nice message can be shown at the end.
|
||||
backup=1
|
||||
# Create backup dir if it doesn't already exist.
|
||||
[[ -e "$backup_dir" ]] || mkdir -p "$backup_dir"
|
||||
# Backup file / link / whatever.
|
||||
mv "$dest" "$backup_dir"
|
||||
fi
|
||||
fi
|
||||
# Do stuff.
|
||||
"$1_do" "$base" "$file"
|
||||
|
@ -390,109 +380,18 @@ function do_stuff() {
|
|||
# Set the prompt delay to be longer for the very first run.
|
||||
export prompt_delay=5; is_dotfiles_bin || prompt_delay=15
|
||||
|
||||
# Keep-alive: update existing sudo time stamp if set, otherwise do nothing.
|
||||
# Note that this doesn't work with Homebrew, since brew explicitly invalidates
|
||||
# the sudo timestamp, which is probably wise.
|
||||
# See https://gist.github.com/cowboy/3118588
|
||||
while true; do sudo -n true; sleep 10; kill -0 "$$" || exit; done 2>/dev/null &
|
||||
|
||||
# Install a custom sudoers file that allows "sudo apt-get" to be executed
|
||||
# without asking for a password.
|
||||
sudoers_file=/etc/sudoers.d/cowboy-dotfiles
|
||||
# Contents of the sudoers file.
|
||||
function sudoers_text() {
|
||||
cat <<EOF
|
||||
# This file was created by cowboy's dotfiles script on $(date -I)
|
||||
# (which will never update it, only recreate it if it's missing)
|
||||
# Sudoers reference: http://ubuntuforums.org/showthread.php?t=1132821
|
||||
|
||||
# Command aliases.
|
||||
Cmnd_Alias APT = /usr/bin/apt-get
|
||||
|
||||
# Members of the sudo and admin groups can run these commands without password.
|
||||
%sudo ALL=(ALL) ALL, NOPASSWD:APT
|
||||
%admin ALL=(ALL) ALL, NOPASSWD:APT
|
||||
EOF
|
||||
}
|
||||
# Bash commands to update the sudoers file.
|
||||
function sudoers_code() {
|
||||
cat <<EOF
|
||||
echo "$(sudoers_text)" > $sudoers_file
|
||||
chmod 0440 $sudoers_file
|
||||
if visudo -c; then
|
||||
echo; echo "Sudoers file created."
|
||||
else
|
||||
rm $sudoers_file
|
||||
echo; echo "Unable to create sudoers file."
|
||||
fi
|
||||
EOF
|
||||
}
|
||||
# Offer to create the sudoers file if it doesn't exist.
|
||||
if is_ubuntu && [[ ! -e $sudoers_file ]]; then
|
||||
cat <<EOF
|
||||
|
||||
The sudoers file can be updated to allow "sudo apt-get" to be executed
|
||||
without asking for a password. You can verify that this worked correctly by
|
||||
running "sudo -k apt-get". If it doesn't ask for a password, and the output
|
||||
looks normal, it worked.
|
||||
|
||||
THIS SHOULD ONLY BE ATTEMPTED IF YOU ARE LOGGED IN AS ROOT IN ANOTHER SHELL.
|
||||
|
||||
This will be skipped if "Y" isn't pressed within the next $prompt_delay seconds.
|
||||
EOF
|
||||
read -N 1 -t $prompt_delay -p "Update sudoers file? [y/N] " update_sudoers; echo
|
||||
if [[ "$update_sudoers" =~ [Yy] ]]; then
|
||||
e_header "Creating sudoers file"
|
||||
sudo bash -c "$(sudoers_code)"
|
||||
else
|
||||
echo "Skipping."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure that we can actually, like, compile anything.
|
||||
if [[ ! "$(type -P gcc)" ]] && is_osx; then
|
||||
e_error "XCode or the Command Line Tools for XCode must be installed first."
|
||||
if [[ ! "$(type -P gcc)" ]]; then
|
||||
e_error "gcc should be installed. It isn't. Aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If Git is not installed, install it (Ubuntu only, since Git comes standard
|
||||
# with recent XCode or CLT)
|
||||
if [[ ! "$(type -P git)" ]] && is_ubuntu; then
|
||||
e_header "Installing Git"
|
||||
sudo apt-get -qq install git-core
|
||||
fi
|
||||
|
||||
# If Git isn't installed by now, something exploded. We gots to quit!
|
||||
if [[ ! "$(type -P git)" ]]; then
|
||||
e_error "Git should be installed. It isn't. Aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialize.
|
||||
if [[ ! -d $DOTFILES ]]; then
|
||||
# Dotfiles directory doesn't exist? Clone it!
|
||||
e_header "Downloading dotfiles"
|
||||
git clone --branch ${DOTFILES_GH_BRANCH:-master} --recursive \
|
||||
git://github.com/${DOTFILES_GH_USER:-cowboy}/dotfiles.git $DOTFILES
|
||||
cd $DOTFILES
|
||||
elif [[ "$1" != "restart" ]]; then
|
||||
# Make sure we have the latest files.
|
||||
e_header "Updating dotfiles"
|
||||
cd $DOTFILES
|
||||
prev_head="$(git rev-parse HEAD)"
|
||||
git pull
|
||||
git submodule update --init --recursive --quiet
|
||||
if [[ "$(git rev-parse HEAD)" != "$prev_head" ]]; then
|
||||
if is_dotfiles_bin; then
|
||||
e_header "Changes detected, restarting script"
|
||||
exec "$0" restart
|
||||
else
|
||||
e_header "Changes detected, please re-run script"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add binaries into the path
|
||||
[[ -d $DOTFILES/bin ]] && export PATH=$DOTFILES/bin:$PATH
|
||||
|
||||
|
@ -503,20 +402,11 @@ shopt -s nullglob
|
|||
# Create caches dir and init subdir, if they don't already exist.
|
||||
mkdir -p "$DOTFILES/caches/init"
|
||||
|
||||
# If backups are needed, this is where they'll go.
|
||||
backup_dir="$DOTFILES/backups/$(date "+%Y_%m_%d-%H_%M_%S")/"
|
||||
backup=
|
||||
|
||||
# Execute code for each file in these subdirectories.
|
||||
do_stuff copy
|
||||
do_stuff link
|
||||
do_stuff config
|
||||
do_stuff init
|
||||
|
||||
# Alert if backups were made.
|
||||
if [[ "$backup" ]]; then
|
||||
echo -e "\nBackups were moved to ~/${backup_dir#$HOME/}"
|
||||
fi
|
||||
|
||||
# All done!
|
||||
e_header "All done!"
|
||||
|
|
392
bin/ical2org.awk
392
bin/ical2org.awk
|
@ -1,392 +0,0 @@
|
|||
#!/usr/bin/awk -f
|
||||
# awk script for converting an iCal formatted file to a sequence of org-mode headings.
|
||||
# this may not work in general but seems to work for day and timed events from Google's
|
||||
# calendar, which is really all I need right now...
|
||||
#
|
||||
# usage:
|
||||
# awk -f THISFILE < icalinputfile.ics > orgmodeentries.org
|
||||
#
|
||||
# Note: change org meta information generated below for author and
|
||||
# email entries!
|
||||
#
|
||||
# Caveats:
|
||||
#
|
||||
# - date entries with no time specified are assumed to be local time zone;
|
||||
# same remark for date entries that do have a time but do not end with Z
|
||||
# e.g.: 20130101T123456 is local and will be kept as 2013-01-01 12:34
|
||||
# where 20130223T123422Z is UTC and will be corrected appropriately
|
||||
#
|
||||
# - UTC times are changed into local times, using the time zone of the
|
||||
# computer that runs the script; it would be very hard in an awk script
|
||||
# to respect the time zone of a file belonging to another time zone:
|
||||
# the offsets will be different as well as the switchover time(s);
|
||||
# (consider a remote shell to a computer with the file's time zone)
|
||||
#
|
||||
# - the UTC conversion entirely relies on the built-in strftime method;
|
||||
# the author is not responsible for any erroneous conversions nor the
|
||||
# consequence of such conversions
|
||||
#
|
||||
# - does process RRULE recurring events, but ignores COUNT specifiers
|
||||
#
|
||||
# - does not process EXDATE to exclude date(s) from recurring events
|
||||
#
|
||||
# Eric S Fraga
|
||||
# 20100629 - initial version
|
||||
# 20100708 - added end times to timed events
|
||||
# - adjust times according to time zone information
|
||||
# - fixed incorrect transfer for entries with ":" embedded within the text
|
||||
# - added support for multi-line summary entries (which become headlines)
|
||||
# 20100709 - incorporated time zone identification
|
||||
# - fixed processing of continuation lines as Google seems to
|
||||
# have changed, in the last day, the number of spaces at
|
||||
# the start of the line for each continuation...
|
||||
# - remove backslashes used to protect commas in iCal text entries
|
||||
# no further revision log after this as the file was moved into a git
|
||||
# repository...
|
||||
#
|
||||
# Updated by: Guido Van Hoecke <guivhoATgmailDOTcom>
|
||||
# Last change: 2013.05.26 14:28:33
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
BEGIN {
|
||||
### config section
|
||||
|
||||
# maximum age in days for entries to be output: set this to -1 to
|
||||
# get all entries or to N>0 to only get enties that start or end
|
||||
# less than N days ago
|
||||
max_age = 7;
|
||||
|
||||
# set to 1 or 0 to yes or not output a header block with TITLE,
|
||||
# AUTHOR, EMAIL etc...
|
||||
header = 1;
|
||||
|
||||
# set to 1 or 0 to yes or not output the original ical preamble as
|
||||
# comment
|
||||
preamble = 1;
|
||||
|
||||
# set to 1 to output time and summary as one line starting with
|
||||
# the time (value 1) or to 0 to output the summary as first line
|
||||
# and the date and time info as a second line
|
||||
condense = 0;
|
||||
|
||||
# set to 1 or 0 to yes or not output the original ical entry as a
|
||||
# comment (mostly useful for debugging purposes)
|
||||
original = 1;
|
||||
|
||||
# google truncates long subjects with ... which is misleading in
|
||||
# an org file: it gives the unfortunate impression that an
|
||||
# expanded entry is still collapsed; value 1 will trim those
|
||||
# ... and value 0 doesn't touch them
|
||||
trimdots = 1;
|
||||
|
||||
# change this to your name
|
||||
author = "Eric S Fraga"
|
||||
|
||||
# and to your email address
|
||||
emailaddress = "e.fraga@ucl.ac.uk"
|
||||
|
||||
### end config section
|
||||
|
||||
# use a colon to separate the type of data line from the actual contents
|
||||
FS = ":";
|
||||
|
||||
# we only need to preserve the original entry lines if either the
|
||||
# preamble or original options are true
|
||||
preserve = preamble || original
|
||||
first = 1; # true until an event has been found
|
||||
max_age_seconds = max_age*24*60*60
|
||||
|
||||
if (header) {
|
||||
print "#+TITLE: Main Google calendar entries"
|
||||
print "#+AUTHOR: ", author
|
||||
print "#+EMAIL: ", emailaddress
|
||||
print "#+DESCRIPTION: converted using the ical2org awk script"
|
||||
print "#+CATEGORY: google"
|
||||
print "#+STARTUP: hidestars"
|
||||
print "#+STARTUP: overview"
|
||||
print ""
|
||||
}
|
||||
}
|
||||
|
||||
# continuation lines (at least from Google) start with a space
|
||||
# if the continuation is after a description or a summary, append the entry
|
||||
# to the respective variable
|
||||
|
||||
/^[ ]/ {
|
||||
if (indescription) {
|
||||
entry = entry gensub("\r", "", "g", gensub("^[ ]", "", "", $0));
|
||||
} else if (insummary) {
|
||||
summary = summary gensub("\r", "", "g", gensub("^[ ]", "", "", $0))
|
||||
}
|
||||
if (preserve)
|
||||
icalentry = icalentry "\n" $0
|
||||
}
|
||||
|
||||
/^BEGIN:VEVENT/ {
|
||||
# start of an event: initialize global velues used for each event
|
||||
date = "";
|
||||
entry = ""
|
||||
headline = ""
|
||||
icalentry = "" # the full entry for inspection
|
||||
id = ""
|
||||
indescription = 0;
|
||||
insummary = 0
|
||||
intfreq = "" # the interval and frequency for repeating org timestamps
|
||||
lasttimestamp = -1;
|
||||
location = ""
|
||||
rrend = ""
|
||||
status = ""
|
||||
summary = ""
|
||||
|
||||
# if this is the first event, output the preamble from the iCal file
|
||||
if (first) {
|
||||
if(preamble) {
|
||||
print "* COMMENT original iCal preamble"
|
||||
print gensub("\r", "", "g", icalentry)
|
||||
}
|
||||
if (preserve)
|
||||
icalentry = ""
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
# any line that starts at the left with a non-space character is a new data field
|
||||
|
||||
/^[A-Z]/ {
|
||||
# we do not copy DTSTAMP lines as they change every time you download
|
||||
# the iCal format file which leads to a change in the converted
|
||||
# org file as I output the original input. This change, which is
|
||||
# really content free, makes a revision control system update the
|
||||
# repository and confuses.
|
||||
if (preserve)
|
||||
if (! index("DTSTAMP", $1))
|
||||
icalentry = icalentry "\n" $0
|
||||
# this line terminates the collection of description and summary entries
|
||||
indescription = 0;
|
||||
insummary = 0;
|
||||
}
|
||||
|
||||
# this type of entry represents a day entry, not timed, with date stamp YYYYMMDD
|
||||
|
||||
/^DTSTART;VALUE=DATE/ {
|
||||
date = datestring($2);
|
||||
}
|
||||
|
||||
/^DTEND;VALUE=DATE/ {
|
||||
time2 = datestring($2, 1);
|
||||
if ( issameday )
|
||||
time2 = ""
|
||||
}
|
||||
|
||||
# this represents a timed entry with date and time stamp YYYYMMDDTHHMMSS
|
||||
# we ignore the seconds
|
||||
|
||||
/^DTSTART[:;][^V]/ {
|
||||
date = datetimestring($2);
|
||||
# print date;
|
||||
}
|
||||
|
||||
# and the same for the end date;
|
||||
|
||||
/^DTEND[:;][^V]/ {
|
||||
time2 = datetimestring($2);
|
||||
if (substr(date,1,10) == substr(time2,1,10)) {
|
||||
# timespan within same date, use one date with a time range
|
||||
date = date "-" substr(time2, length(time2)-4)
|
||||
time2 = ""
|
||||
}
|
||||
}
|
||||
|
||||
# repetition rule
|
||||
|
||||
/^RRULE:FREQ=(DAILY|WEEKLY|MONTHLY|YEARLY)/ {
|
||||
# get the d, w, m or y value
|
||||
freq = tolower(gensub(/.*FREQ=(.).*/, "\\1", $0))
|
||||
# get the interval, and use 1 if none specified
|
||||
interval = $2 ~ /INTERVAL=/ ? gensub(/.*INTERVAL=([0-9]+);.*/, "\\1", $2) : 1
|
||||
# get the enddate of the rule and use "" if none specified
|
||||
rrend = $2 ~ /UNTIL=/ ? datestring(gensub(/.*UNTIL=([0-9]{8}).*/, "\\1", $2)) : ""
|
||||
# build the repetitor vale as understood by org
|
||||
intfreq = " +" interval freq
|
||||
# if the repetition is daily, and there is an end date, drop the repetitor
|
||||
# as that is the default
|
||||
if (intfreq == " +1d" && time2 =="" && rrend != "")
|
||||
intfreq = ""
|
||||
}
|
||||
|
||||
# The description will the contents of the entry in org-mode.
|
||||
# this line may be continued.
|
||||
|
||||
/^DESCRIPTION/ {
|
||||
$1 = "";
|
||||
entry = entry gensub("\r", "", "g", $0);
|
||||
indescription = 1;
|
||||
}
|
||||
|
||||
# the summary will be the org heading
|
||||
|
||||
/^SUMMARY/ {
|
||||
$1 = "";
|
||||
summary = gensub("\r", "", "g", $0);
|
||||
|
||||
# trim trailing dots if requested by config option
|
||||
if(trimdots && summary ~ /\.\.\.$/)
|
||||
sub(/\.\.\.$/, "", summary)
|
||||
insummary = 1;
|
||||
}
|
||||
|
||||
# the unique ID will be stored as a property of the entry
|
||||
|
||||
/^UID/ {
|
||||
id = gensub("\r", "", "g", $2);
|
||||
}
|
||||
|
||||
/^LOCATION/ {
|
||||
location = gensub("\r", "", "g", $2);
|
||||
}
|
||||
|
||||
/^STATUS/ {
|
||||
status = gensub("\r", "", "g", $2);
|
||||
}
|
||||
|
||||
# when we reach the end of the event line, we output everything we
|
||||
# have collected so far, creating a top level org headline with the
|
||||
# date/time stamp, unique ID property and the contents, if any
|
||||
|
||||
/^END:VEVENT/ {
|
||||
#output event
|
||||
if(max_age<0 || ( lasttimestamp>0 && systime()<lasttimestamp+max_age_seconds ) )
|
||||
{
|
||||
# build org timestamp
|
||||
if (intfreq != "")
|
||||
date = date intfreq
|
||||
if (time2 != "")
|
||||
date = date ">--<" time2
|
||||
else if (rrend != "")
|
||||
date = date ">--<" rrend
|
||||
|
||||
# translate \n sequences to actual newlines and unprotect commas (,)
|
||||
if (condense)
|
||||
print "* <" date "> " gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)))
|
||||
else
|
||||
print "* " gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)))
|
||||
print ":PROPERTIES:"
|
||||
print ":ID: " id
|
||||
if(length(location))
|
||||
print ":LOCATION: " location
|
||||
if(length(status))
|
||||
print ":STATUS: " status
|
||||
print ":END:"
|
||||
if (! condense)
|
||||
print "<" date ">"
|
||||
print ""
|
||||
# translate \n sequences to actual newlines and unprotect commas (,)
|
||||
if(length(entry)>1)
|
||||
print gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", "\n", "g", entry)));
|
||||
|
||||
# output original entry if requested by 'original' config option
|
||||
if (original)
|
||||
print "** COMMENT original iCal entry\n", gensub("\r", "", "g", icalentry)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
# funtion to convert an iCal time string 'yyyymmddThhmmss[Z]' into a
|
||||
# date time string as used by org, preferably including the short day
|
||||
# of week: 'yyyy-mm-dd day hh:mm' or 'yyyy-mm-dd hh:mm' if we cannot
|
||||
# define the day of the week
|
||||
|
||||
function datetimestring(input)
|
||||
{
|
||||
# print "________"
|
||||
# print "input : " input
|
||||
# convert the iCal Date+Time entry to a format that mktime can understand
|
||||
spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 \\4 \\5 \\6", "g", input);
|
||||
# print "spec :" spec
|
||||
|
||||
stamp = mktime(spec);
|
||||
lasttimestamp = stamp;
|
||||
|
||||
if (stamp <= 0) {
|
||||
# this is a date before the start of the epoch, so we cannot
|
||||
# use strftime and will deliver a 'yyyy-mm-dd hh:mm' string
|
||||
# without day of week; this assumes local time, and does not
|
||||
# attempt UTC offset correction
|
||||
spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3 \\4:\\5", "g", input);
|
||||
# print "==> spec:" spec;
|
||||
return spec;
|
||||
}
|
||||
|
||||
if (input ~ /[0-9]{8}T[0-9]{6}Z/ ) {
|
||||
# this is an utc time;
|
||||
# we need to correct the timestamp by the utc offset for this time
|
||||
offset = strftime("%z", stamp)
|
||||
pm = substr(offset,1,1) 1 # define multiplier +1 or -1
|
||||
hh = substr(offset,2,2) * 3600 * pm
|
||||
mm = substr(offset,4,2) * 60 * pm
|
||||
|
||||
# adjust the timestamp
|
||||
stamp = stamp + hh + mm
|
||||
}
|
||||
|
||||
return strftime("%Y-%m-%d %a %H:%M", stamp);
|
||||
}
|
||||
|
||||
# function to convert an iCal date into an org date;
|
||||
# the optional parameter indicates whether this is an end date;
|
||||
# for single or multiple whole day events, the end date given by
|
||||
# iCal is the date of the first day after the event;
|
||||
# if the optional 'isenddate' parameter is non zero, this function
|
||||
# tries to reduce the given date by one day
|
||||
|
||||
function datestring(input, isenddate)
|
||||
{
|
||||
#convert the iCal string to a an mktime input string
|
||||
spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 00 00 00", "g", input);
|
||||
|
||||
# compute the nr of seconds after or before the epoch
|
||||
# dates before the epoch will have a negative timestamp
|
||||
# days after the epoch will have a positive timestamp
|
||||
stamp = mktime(spec);
|
||||
|
||||
if (isenddate) {
|
||||
# subtract 1 day from the timestamp
|
||||
# note that this also works for dates before the epoch
|
||||
stamp = stamp - 86400;
|
||||
|
||||
# register whether the end date is same as the start date
|
||||
issameday = lasttimestamp == stamp
|
||||
}
|
||||
# save timestamp to allow for check of max_age
|
||||
lasttimestamp = stamp
|
||||
|
||||
if (stamp < 0) {
|
||||
# this date is before the epoch;
|
||||
# the returned datestring will not have the short day of week string
|
||||
# as strftime does not handle negative times;
|
||||
# we have to construct the datestring directly from the input
|
||||
if (isenddate) {
|
||||
# we really should return the date before the input date, but strftime
|
||||
# does not work with negative timestamp values; so we can not use it
|
||||
# to obtain the string representation of the corrected timestamp;
|
||||
# we have to return the date specified in the iCal input and we
|
||||
# add time 00:00 to clarify this
|
||||
return spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3 00:00", "g", input);
|
||||
} else {
|
||||
# just generate the desired representation of the input date, without time;
|
||||
return gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3", "g", input);
|
||||
}
|
||||
}
|
||||
|
||||
# return the date and day of week
|
||||
return strftime("%Y-%m-%d %a", stamp);
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# time-stamp-line-limit: 1000
|
||||
# time-stamp-format: "%04y.%02m.%02d %02H:%02M:%02S"
|
||||
# time-stamp-active: t
|
||||
# time-stamp-start: "Last change:[ \t]+"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
|
@ -4,6 +4,6 @@ wget -O "${HOME}/bin/cpanm" https://cpanmin.us/
|
|||
chmod +x "${HOME}/bin/cpanm"
|
||||
|
||||
# Bootstrap local lib
|
||||
cpanm -n --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
|
||||
cpanm -n --local-lib=~/perl5 local::lib && eval "$(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)"
|
||||
# Linting / tidy
|
||||
cpanm -n --local-lib=~/perl5 Perl::Critic Perl::Tidy
|
||||
|
|
|
@ -5,7 +5,7 @@ python3 /tmp/get-pip.py --user
|
|||
# Environment management
|
||||
pip install --user virtualenv pipenv
|
||||
# Language Server Protocol
|
||||
pip install --user python-language-server[all]
|
||||
pip install --user "python-language-server[all]"
|
||||
# Linters
|
||||
pip install --user flake8 pylint yamllint yamlfmt
|
||||
# Formatting
|
||||
|
|
26
bin/isip
26
bin/isip
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then cat <<HELP
|
||||
Get all bound IPs
|
||||
http://benalman.com/
|
||||
|
||||
Usage: $(basename "$0") [IP]
|
||||
|
||||
If an IP is specified and it is bound to a network interface, echo it,
|
||||
otherwise echo nothing.
|
||||
|
||||
Copyright (c) 2012 "Cowboy" Ben Alman
|
||||
Licensed under the MIT license.
|
||||
http://benalman.com/about/license/
|
||||
HELP
|
||||
exit; fi
|
||||
|
||||
iplist=$(ifconfig -a | perl -nle'/inet (?:addr:)?(\d+\.\d+\.\d+\.\d+)/ && print $1')
|
||||
|
||||
if [ "$1" ]; then
|
||||
if [ "$(echo $iplist | grep -w $1)" ]; then
|
||||
echo $1
|
||||
fi
|
||||
else
|
||||
echo $iplist
|
||||
fi
|
5
bin/kxt
5
bin/kxt
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
mpc clear
|
||||
mpc add http://kera-ice.streamguys.us:80/kxtlive128
|
||||
mpc play
|
||||
|
13
bin/lock
13
bin/lock
|
@ -1,13 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# On Linux machines I'm in a DE so use loginctl
|
||||
if [ -x /bin/loginctl ]; then
|
||||
loginctl lock-session
|
||||
exit
|
||||
fi
|
||||
|
||||
# Fall back to straight i3lock
|
||||
scrot /tmp/screen_locked.png
|
||||
convert /tmp/screen_locked.png -blur 10x10 /tmp/screen_locked2.png
|
||||
i3lock -i /tmp/screen_locked2.png
|
||||
|
43
bin/manh
43
bin/manh
|
@ -1,43 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then cat <<HELP
|
||||
Manpage-as-HTML Viewer
|
||||
http://benalman.com/
|
||||
|
||||
Usage: $(basename "$0") [section] name
|
||||
|
||||
View a manpage as HTML in the default viewer. Because sometimes
|
||||
you don't want to view manpages in the terminal.
|
||||
|
||||
Copyright (c) 2012 "Cowboy" Ben Alman
|
||||
Licensed under the MIT license.
|
||||
http://benalman.com/about/license/
|
||||
HELP
|
||||
exit; fi
|
||||
|
||||
if [ ! "$1" ]; then
|
||||
echo 'What manual page do you want?!'
|
||||
exit
|
||||
fi
|
||||
|
||||
cache_dir=$DOTFILES/caches/manh
|
||||
|
||||
# Figure out what the filename should be.
|
||||
file="$cache_dir/${2:+$2.}$1.html"
|
||||
|
||||
# Create directory if it doesn't exist.
|
||||
[[ -e "$cache_dir" ]] || mkdir -p "$cache_dir"
|
||||
|
||||
# Create HTML if it doesn't exist.
|
||||
[[ ! -e "$file" ]] && man "$@" >/dev/null && cat > "$file" <<EOF
|
||||
<!doctype html>
|
||||
<html>
|
||||
<link rel="stylesheet" href="../../conf/manh/styles.css">
|
||||
<body>
|
||||
$(man "$@" 2>/dev/null | man2html -bare -nodepage)
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# Open HTML (if it does exist).
|
||||
[[ -e "$file" ]] && open "$file"
|
35
bin/manp
35
bin/manp
|
@ -1,35 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then cat <<HELP
|
||||
Manpage-as-PDF Viewer
|
||||
http://benalman.com/
|
||||
|
||||
Usage: $(basename "$0") [section] name
|
||||
|
||||
View a manpage as PDF in the default viewer (Preview.app). Because sometimes
|
||||
you don't want to view manpages in the terminal.
|
||||
|
||||
Copyright (c) 2012 "Cowboy" Ben Alman
|
||||
Licensed under the MIT license.
|
||||
http://benalman.com/about/license/
|
||||
HELP
|
||||
exit; fi
|
||||
|
||||
if [ ! "$1" ]; then
|
||||
echo 'What manual page do you want?!'
|
||||
exit
|
||||
fi
|
||||
|
||||
cache_dir=$DOTFILES/caches/manpdf
|
||||
|
||||
# Figure out what the filename should be.
|
||||
file="$cache_dir/${2:+$2.}$1.pdf"
|
||||
|
||||
# Create directory if it doesn't exist.
|
||||
[[ -e "$cache_dir" ]] || mkdir -p "$cache_dir"
|
||||
|
||||
# Create PDF if it doesn't exist.
|
||||
[[ -e "$file" ]] || man -t "$@" | pstopdf -i -o "$file" >/dev/null 2>&1
|
||||
|
||||
# Open PDF (if it does exist).
|
||||
[[ -e "$file" ]] && open "$file"
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
sudo mount -t cifs -o user=dtrudg,uid=1000,gid=1001 //192.168.1.210/USB_SSD /mnt/USB_SSD
|
||||
sudo mount -t cifs -o user=dtrudg,uid=1000,gid=1001 //192.168.1.210/USB_SSD /mnt/dtrudg
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
INTERPRETER=$(patchelf --print-interpreter /bin/sh)
|
||||
patchelf --set-interpreter "${INTERPRETER}" $1
|
||||
|
23
bin/pid
23
bin/pid
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then cat <<HELP
|
||||
Get PIDs
|
||||
http://benalman.com/
|
||||
|
||||
Usage: $(basename "$0") [processname [processname ...]]
|
||||
|
||||
Get the PIDs of all matching processes for all specified processnames.
|
||||
If no arguments are passed, list processes by PID, TTY, USER, COMMAND.
|
||||
|
||||
Copyright (c) 2012 "Cowboy" Ben Alman
|
||||
Licensed under the MIT license.
|
||||
http://benalman.com/about/license/
|
||||
HELP
|
||||
exit; fi
|
||||
|
||||
if [ ! "$1" ]; then
|
||||
ps axo pid,tty,user,command
|
||||
else
|
||||
args="$1"; shift; for arg in "$@"; do args="${args}|${arg}"; done
|
||||
echo $(ps axo pid,tty,user,command | perl -nle"m#^\s*(\d+).*(?:$args)# && !m#.dotfiles/bin/pid# && print \$1")
|
||||
fi
|
310
bin/rename
310
bin/rename
|
@ -1,310 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
rename - renames multiple files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
F<rename>
|
||||
S<B<-h>>
|
||||
|
||||
F<rename>
|
||||
S<B<--man>>
|
||||
|
||||
F<rename>
|
||||
S<B<[ -0 ]>>
|
||||
S<B<[ -c ]>>
|
||||
S<B<[ -C ]>>
|
||||
S<B<[ -e code ]>>
|
||||
S<B<[ -f ]>>
|
||||
S<B<[ -i ]>>
|
||||
S<B<[ -l | -L ]>>
|
||||
S<B<[ -n ]>>
|
||||
S<B<[ -s from to ]>>
|
||||
S<B<[ -v ]>>
|
||||
S<B<[ files ]>>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<rename> renames the filenames supplied according to the rules specified. If a given filename is not modified, it will not be renamed. If no filenames are given on the command line, filenames will be read via standard input.
|
||||
|
||||
For example, to rename all files matching C<*.bak> to strip the extension, you might say
|
||||
|
||||
rename 's/\.bak$//' *.bak
|
||||
|
||||
If are confident that none of the filenames has C<.bak> anywhere else than at the end, you can also use the much easier typed
|
||||
|
||||
rename -s .bak '' *.bak
|
||||
|
||||
You can always do multiple changes in one ago:
|
||||
|
||||
rename -s .tgz .tar.gz -s .tbz2 .tar.bz2 *.tar.*
|
||||
|
||||
Note however that expressive options are order sensitive. The following would probably surprise you:
|
||||
|
||||
rename -s foo bar -s bar baz *
|
||||
|
||||
Since operations are cumulative, this would end up substituting (some of) the F<foo> matches in filenames with F<baz>! So pay attention to order. You may want to request a verbose dry run with C<-nv> for the first stab at a complex rename operation.
|
||||
|
||||
rename -nv -s bar baz -s foo bar *
|
||||
|
||||
You can combine the various expressive options to suit your needs. F.ex files from Microsoft(tm) Windows systems often have blanks and (sometimes nothing but) capital letters in their names. Let's say you have a bunch of such files to clean up, and you also want to move them to subdirectories based on extension. The following command should help, provided all directories already exist:
|
||||
|
||||
rename -cz -e '$_ = "$1/$_" if /(\..*)\z/' *
|
||||
|
||||
Again you need to pay attention to order sensitivity for expressive options. If you placed the C<-c> after the C<-e> in the above example, files with F<.zip> and F<.ZIP> extensions would be (attempted to be) moved to different directories because the directory name prefix would be added before the filenames were normalized. Once again, use verbose dry run requested using C<-nv> to get an idea of what exactly a complex rename operation is going to do.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-h>, B<--help>
|
||||
|
||||
See a synopsis.
|
||||
|
||||
=item B<--man>
|
||||
|
||||
Browse the manpage.
|
||||
|
||||
=back
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-0>, B<--null>
|
||||
|
||||
When reading file names from C<STDIN>, split on NUL bytes instead of newlines. This is useful in combination with GNU find's C<-print0> option, GNU grep's C<-Z> option, and GNU sort's C<-z> option, to name just a few. B<Only valid if no filenames have been given on the commandline.>
|
||||
|
||||
=item B<-c>, B<--lower-case>
|
||||
|
||||
Converts file names to all lower case.
|
||||
|
||||
=item B<-C>, B<--upper-case>
|
||||
|
||||
Converts file names to all upper case.
|
||||
|
||||
=item B<-e>, B<--expr>
|
||||
|
||||
The C<code> argument to this option should be a Perl expression that assumes the filename in the C<$_> variable and modifies it for the filenames to be renamed. When no other C<-c>, C<-C>, C<-e>, C<-s>, or C<-z> options are given, you can omit the C<-e> from infront of the code.
|
||||
|
||||
=item B<-g>, B<--glob>
|
||||
|
||||
Glob filename arguments. This is useful if you're using a braindead shell such as F<cmd.exe> which won't expand wildcards on behalf of the user.
|
||||
|
||||
=item B<-f>, B<--force>
|
||||
|
||||
Rename even when a file with the destination name already exists.
|
||||
|
||||
=item B<-i>, B<--interactive>
|
||||
|
||||
Ask the user to confirm every action before it is taken.
|
||||
|
||||
=item B<-k>, B<--backwards>, B<--reverse-order>
|
||||
|
||||
Process the list of files in reverse order, last file first. This prevents conflicts when renaming files to names which are currently taken but would be freed later during the process of renaming.
|
||||
|
||||
=item B<-l>, B<--symlink>
|
||||
|
||||
Create symlinks from the new names to the existing ones, instead of renaming the files. B<Cannot be used in conjunction with C<-L>.>
|
||||
|
||||
=item B<-L>, B<--hardlink>
|
||||
|
||||
Create hard links from the new names to the existing ones, instead of renaming the files. B<Cannot be used in conjunction with C<-l>.>
|
||||
|
||||
=item B<-n>, B<--dry-run>, B<--just-print>
|
||||
|
||||
Show how the files would be renamed, but don't actually do anything.
|
||||
|
||||
=item B<-s>, B<--subst>, B<--simple>
|
||||
|
||||
Perform a simple textual substitution of C<from> to C<to>. The C<from> and C<to> parameters must immediately follow the argument.
|
||||
|
||||
Quoting issues aside, this is equivalent to supplying a C<-e 's/\Qfrom/to/'>.
|
||||
|
||||
=item B<-v>, B<--verbose>
|
||||
|
||||
Print additional information about the operations (not) executed.
|
||||
|
||||
=item B<-z>, B<--sanitize>
|
||||
|
||||
Replaces consecutive blanks, shell meta characters, and control characters in filenames with underscores.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
mv(1), perl(1), find(1), grep(1), sort(1)
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None currently known.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Aristotle Pagaltzis
|
||||
|
||||
Idea, inspiration and original code from Larry Wall and Robin Barker.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
|
||||
use Pod::Usage;
|
||||
use Getopt::Long 2.24, qw(:config bundling no_ignore_case no_auto_abbrev);
|
||||
|
||||
use constant ERROR => do { bless \(my $l = 0), 'LOGLEVEL' };
|
||||
use constant INFO => do { bless \(my $l = 1), 'LOGLEVEL' };
|
||||
use constant DEBUG => do { bless \(my $l = 2), 'LOGLEVEL' };
|
||||
use constant VERB_FOR => {
|
||||
link => {
|
||||
inf => 'link',
|
||||
pastp => 'linked',
|
||||
exec => sub { link shift, shift or die },
|
||||
},
|
||||
symlink => {
|
||||
inf => 'symlink',
|
||||
pastp => 'symlinked',
|
||||
exec => sub { symlink shift, shift or die },
|
||||
},
|
||||
rename => {
|
||||
inf => 'rename',
|
||||
pastp => 'renamed',
|
||||
exec => sub { rename shift, shift or die },
|
||||
},
|
||||
};
|
||||
|
||||
sub argv_to_subst_expr {
|
||||
my $modifier = shift || '';
|
||||
pod2usage( -verbose => 1 ) if @ARGV < 2;
|
||||
my ($from, $to) = map quotemeta, splice @ARGV, 0, 2;
|
||||
# the ugly \${\""} construct is necessary because unknown backslash escapes are
|
||||
# not treated the same in pattern- vs doublequote-quoting context; only the
|
||||
# latter lets us do the right thing with problematic input like
|
||||
# ']{ool(haracter$' or maybe '>><//((/>'
|
||||
sprintf 's/\Q${\"%s"}/%s/%s', $from, $to, $modifier;
|
||||
}
|
||||
|
||||
my @EXPR;
|
||||
|
||||
GetOptions(
|
||||
'h|help' => sub { pod2usage( -verbose => 1 ) },
|
||||
'man' => sub { pod2usage( -verbose => 2 ) },
|
||||
'0|null' => \my $opt_null,
|
||||
'c|lower-case' => sub { push @EXPR, 's/([[:upper:]]+)/\L$1/g' },
|
||||
'C|upper-case' => sub { push @EXPR, 's/([[:lower:]]+)/\U$1/g' },
|
||||
'e|expr=s' => \@EXPR,
|
||||
'f|force' => \my $opt_force,
|
||||
'g|glob' => \my $opt_glob,
|
||||
'i|interactive' => \my $opt_interactive,
|
||||
'k|backwards|reverse-order' => \my $opt_backwards,
|
||||
'l|symlink' => \my $opt_symlink,
|
||||
'L|hardlink' => \my $opt_hardlink,
|
||||
'n|just-print|dry-run' => \my $opt_dryrun,
|
||||
'p|mkpath|make-dirs' => \my $opt_mkpath,
|
||||
'v|verbose+' => \(my $opt_verbose = 0),
|
||||
'z|sanitize' => sub { push @EXPR, 's/[!"\$&()=?`*\';<>|_[:cntrl:][:blank:]]+/_/g' },
|
||||
's|subst|simple' => sub { push @EXPR, argv_to_subst_expr },
|
||||
'S|subst-global' => sub { push @EXPR, argv_to_subst_expr('g') },
|
||||
) or pod2usage( -verbose => 1 );
|
||||
|
||||
die "TODO" if $opt_mkpath;
|
||||
|
||||
if(not @EXPR) {
|
||||
pod2usage( -verbose => 1 ) if not @ARGV or -e $ARGV[0];
|
||||
push @EXPR, shift;
|
||||
}
|
||||
|
||||
pod2usage( -verbose => 1 )
|
||||
if ($opt_hardlink and $opt_symlink)
|
||||
or ($opt_null and @ARGV);
|
||||
|
||||
++$opt_verbose if $opt_dryrun;
|
||||
|
||||
BEGIN {
|
||||
*CORE::GLOBAL::warn = sub {
|
||||
if(ref $_[0] eq 'LOGLEVEL') {
|
||||
my $msglevel = ${(shift)};
|
||||
print "@_\n" if $opt_verbose >= $msglevel;
|
||||
return;
|
||||
}
|
||||
warn @_;
|
||||
};
|
||||
}
|
||||
|
||||
my $code = do {
|
||||
my $cat = "sub { ".join('; ', @EXPR)." }";
|
||||
warn DEBUG, "Using expression: $cat";
|
||||
|
||||
my $evaled = eval $cat;
|
||||
die $@ if $@;
|
||||
die "Evaluation to subref failed. Check expression using -vn\n"
|
||||
unless 'CODE' eq ref $evaled;
|
||||
|
||||
$evaled;
|
||||
};
|
||||
|
||||
my $verb = VERB_FOR->{
|
||||
$opt_hardlink ? 'link' :
|
||||
$opt_symlink ? 'symlink' :
|
||||
do { 'rename' }
|
||||
};
|
||||
|
||||
if (!@ARGV) {
|
||||
warn INFO, "Reading filenames from STDIN";
|
||||
@ARGV = do {
|
||||
if($opt_null) {
|
||||
warn INFO, "Splitting on NUL bytes";
|
||||
local $/ = "\0";
|
||||
}
|
||||
<STDIN>;
|
||||
};
|
||||
chomp @ARGV;
|
||||
}
|
||||
|
||||
@ARGV = map glob, @ARGV if $opt_glob;
|
||||
|
||||
@ARGV = reverse @ARGV if $opt_backwards;
|
||||
|
||||
for (@ARGV) {
|
||||
my $old = $_;
|
||||
|
||||
$code->();
|
||||
|
||||
if($old eq $_) {
|
||||
warn DEBUG, "'$old' unchanged";
|
||||
next;
|
||||
}
|
||||
|
||||
if(!$opt_force and -e) {
|
||||
warn ERROR, "'$old' not $verb->{pastp}: '$_' already exists";
|
||||
next;
|
||||
}
|
||||
|
||||
if($opt_dryrun) {
|
||||
warn INFO, "'$old' would be $verb->{pastp} to '$_'";
|
||||
next;
|
||||
}
|
||||
|
||||
if($opt_interactive) {
|
||||
print "\u$verb->{inf} '$old' to '$_'? [n] ";
|
||||
if(<STDIN> !~ /^y(?:es)?$/i) {
|
||||
warn DEBUG, "Skipping '$old'.";
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
eval { $verb->{exec}($old, $_) };
|
||||
|
||||
if($@) {
|
||||
warn ERROR, "Can't $verb->{inf} '$old' to '$_': $!";
|
||||
next;
|
||||
}
|
||||
|
||||
warn INFO, "'$old' $verb->{pastp} to '$_'";
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ ! "$1" || "$1" == "-h" || "$1" == "--help" ]]; then cat <<HELP
|
||||
Resample specified images to 72 DPI
|
||||
http://benalman.com/
|
||||
|
||||
Usage: $(basename "$0") [img [img ...]]
|
||||
|
||||
The new MacBook Pro retina display is amazing, but screengrabs taken on
|
||||
one using the screencapture utility aren't scaled to 72 DPI by default.
|
||||
This script scales those images to 72 DPI, making them viewable at a sane
|
||||
resolution in web browsers.
|
||||
|
||||
Copyright (c) 2012 "Cowboy" Ben Alman
|
||||
Licensed under the MIT license.
|
||||
http://benalman.com/about/license/
|
||||
HELP
|
||||
[[ "$1" ]]; exit; fi
|
||||
|
||||
while [[ "$1" ]]; do
|
||||
file="$1"; shift
|
||||
|
||||
dpiWidth=$(sips "$file" -g dpiWidth | awk '/:/ {print $2}')
|
||||
dpiHeight=$(sips "$file" -g dpiHeight | awk '/:/ {print $2}')
|
||||
pixelWidth=$(sips "$file" -g pixelWidth | awk '/:/ {print $2}')
|
||||
pixelHeight=$(sips "$file" -g pixelHeight | awk '/:/ {print $2}')
|
||||
|
||||
if [[ "$(echo "$dpiWidth - 72" | bc)" == "0" || "$(echo "$dpiHeight - 72" | bc)" == "0" ]]; then
|
||||
echo "File $(basename "$file") already ${pixelWidth}x${pixelHeight} pixels @ 72 DPI."
|
||||
continue
|
||||
fi
|
||||
|
||||
w=$(echo "$pixelWidth * 72 / $dpiWidth" | bc)
|
||||
h=$(echo "$pixelHeight * 72 / $dpiHeight" | bc)
|
||||
|
||||
echo "Resampling $(basename "$file") to ${w}x${h} pixels @ 72 DPI."
|
||||
sips "$file" -s dpiWidth 72 -s dpiHeight 72 -z $h $w >/dev/null 2>&1
|
||||
done
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
mpc clear
|
||||
mpc ls | mpc add
|
||||
mpc play
|
||||
|
26
bin/ssid
26
bin/ssid
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then cat <<HELP
|
||||
Get WiFi SSID
|
||||
http://benalman.com/
|
||||
|
||||
Usage: $(basename "$0")
|
||||
|
||||
If an SSID is specified and it is the current WiFi network's SSID, echo it,
|
||||
otherwise echo nothing.
|
||||
|
||||
Copyright (c) 2012 "Cowboy" Ben Alman
|
||||
Licensed under the MIT license.
|
||||
http://benalman.com/about/license/
|
||||
HELP
|
||||
exit; fi
|
||||
|
||||
ssid=$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | grep " SSID" | sed "s/.*: //")
|
||||
|
||||
if [ "$1" ]; then
|
||||
if [ "$(echo $ssid | grep -w $1)" ]; then
|
||||
echo $1
|
||||
fi
|
||||
else
|
||||
echo $ssid
|
||||
fi
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
rsync -avx --delete ~/Org/WebPub/ dctrud@ma.sdf.org:html/
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#!/bin/bash
|
||||
for subdir in $(find . -mindepth 1 -maxdepth 1 -type d); do
|
||||
echo "Compressing $subdir..."
|
||||
base=$(basename "$subdir")
|
||||
tar -cJf "$base.tar.xz" "$base"
|
||||
done
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
wakeonlan "b0:83:fe:9c:80:7c" || wol "b0:83:fe:9c:80:7c"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
wakeonlan "44:39:c4:92:95:8d" || wol "44:39:c4:92:95:8d"
|
|
@ -1,37 +0,0 @@
|
|||
/* Colors from http://ethanschoonover.com/solarized */
|
||||
/* Fonts from http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/design/index-en.html */
|
||||
|
||||
body {
|
||||
color: #839496;
|
||||
background: #002b36;
|
||||
padding: 0;
|
||||
margin: 0 0 3em 1.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #2aa198;
|
||||
}
|
||||
|
||||
b {
|
||||
color: #93a1a1;
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: normal;
|
||||
text-decoration: underline;
|
||||
color: #b58900;
|
||||
}
|
||||
|
||||
h2,
|
||||
pre {
|
||||
font-family: mplus-2m-regular, Monaco, monospace;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: -0.5em 0 -1.5em;
|
||||
}
|
||||
|
||||
body > hr,
|
||||
body > address {
|
||||
display: none;
|
||||
}
|
|
@ -1,6 +1,3 @@
|
|||
[user]
|
||||
name = David Trudgian
|
||||
email = EMAIL
|
||||
[core]
|
||||
excludesfile = ~/.gitignore_global
|
||||
[color]
|
||||
|
|
|
@ -4,7 +4,7 @@ is_osx || return 1
|
|||
# Install Homebrew.
|
||||
if [[ ! "$(type -P brew)" ]]; then
|
||||
e_header "Installing Homebrew"
|
||||
true | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
true | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
fi
|
||||
|
||||
# Exit if, for some reason, Homebrew is not installed.
|
||||
|
|
|
@ -12,10 +12,8 @@ casks=(
|
|||
caffeine
|
||||
emacs
|
||||
firefox
|
||||
iterm2
|
||||
sublime-merge
|
||||
sublime-text
|
||||
tigervnc-viewer
|
||||
xquartz
|
||||
)
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ recipes=(
|
|||
borgbackup
|
||||
coreutils
|
||||
ffmpeg
|
||||
fish
|
||||
fzf
|
||||
gcc
|
||||
git
|
||||
|
|
|
@ -242,6 +242,8 @@ function! plug#begin(...)
|
|||
let home = s:path(s:plug_fnamemodify(s:plug_expand(a:1), ':p'))
|
||||
elseif exists('g:plug_home')
|
||||
let home = s:path(g:plug_home)
|
||||
elseif has('nvim')
|
||||
let home = stdpath('data') . '/plugged'
|
||||
elseif !empty(&rtp)
|
||||
let home = s:path(split(&rtp, ',')[0]) . '/plugged'
|
||||
else
|
||||
|
@ -350,7 +352,7 @@ function! plug#end()
|
|||
endif
|
||||
let lod = { 'ft': {}, 'map': {}, 'cmd': {} }
|
||||
|
||||
if exists('g:did_load_filetypes')
|
||||
if get(g:, 'did_load_filetypes', 0)
|
||||
filetype off
|
||||
endif
|
||||
for name in g:plugs_order
|
||||
|
@ -2619,26 +2621,34 @@ function! s:preview_commit()
|
|||
|
||||
let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}')
|
||||
if empty(sha)
|
||||
return
|
||||
let name = matchstr(getline('.'), '^- \zs[^:]*\ze:$')
|
||||
if empty(name)
|
||||
return
|
||||
endif
|
||||
let title = 'HEAD@{1}..'
|
||||
let command = 'git diff --no-color HEAD@{1}'
|
||||
else
|
||||
let title = sha
|
||||
let command = 'git show --no-color --pretty=medium '.sha
|
||||
let name = s:find_name(line('.'))
|
||||
endif
|
||||
|
||||
let name = s:find_name(line('.'))
|
||||
if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir)
|
||||
return
|
||||
endif
|
||||
|
||||
if exists('g:plug_pwindow') && !s:is_preview_window_open()
|
||||
execute g:plug_pwindow
|
||||
execute 'e' sha
|
||||
execute 'e' title
|
||||
else
|
||||
execute 'pedit' sha
|
||||
execute 'pedit' title
|
||||
wincmd P
|
||||
endif
|
||||
setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable
|
||||
setlocal previewwindow filetype=git buftype=nofile bufhidden=wipe nobuflisted modifiable
|
||||
let batchfile = ''
|
||||
try
|
||||
let [sh, shellcmdflag, shrd] = s:chsh(1)
|
||||
let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha
|
||||
let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && '.command
|
||||
if s:is_win
|
||||
let [batchfile, cmd] = s:batchfile(cmd)
|
||||
endif
|
||||
|
@ -2764,9 +2774,9 @@ function! s:snapshot(force, ...) abort
|
|||
1
|
||||
let anchor = line('$') - 3
|
||||
let names = sort(keys(filter(copy(g:plugs),
|
||||
\'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)')))
|
||||
\'has_key(v:val, "uri") && isdirectory(v:val.dir)')))
|
||||
for name in reverse(names)
|
||||
let sha = s:git_revision(g:plugs[name].dir)
|
||||
let sha = has_key(g:plugs[name], 'commit') ? g:plugs[name].commit : s:git_revision(g:plugs[name].dir)
|
||||
if !empty(sha)
|
||||
call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha))
|
||||
redraw
|
||||
|
|
|
@ -405,7 +405,7 @@ function! plug#end()
|
|||
|
||||
for [map, names] in items(lod.map)
|
||||
for [mode, map_prefix, key_prefix] in
|
||||
\ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
|
||||
\ [['i', '<C-\><C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
|
||||
execute printf(
|
||||
\ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>',
|
||||
\ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix)
|
||||
|
|
|
@ -193,7 +193,6 @@ let g:airline#extensions#tabline#buffer_nr_show = 1
|
|||
let g:plug_threads = 1
|
||||
call plug#begin('~/.vim/plugged')
|
||||
Plug 'airblade/vim-gitgutter'
|
||||
Plug 'dag/vim-fish'
|
||||
Plug 'fatih/vim-go'
|
||||
Plug 'kien/ctrlp.vim'
|
||||
Plug 'tpope/vim-commentary'
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Sane default PATH across Linux, BSD, MacOS
|
||||
#export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R7/bin:/usr/pkg/bin:/usr/pkg/sbin:/usr/games:/usr/local/bin:/usr/local/sbin"
|
||||
|
||||
# Passing the "source" arg tells it to only define functions, then quit.
|
||||
source $DOTFILES/bin/dotfiles "source"
|
||||
source "$DOTFILES/bin/dotfiles" "source"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
export PATH="$HOME/bin:$HOME/.local/bin:$PATH"
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# anaconda
|
||||
|
||||
if [ -d "$HOME/anaconda3/bin" ]; then
|
||||
|
||||
green='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
# echo -e "${green}[dotfiles] anaconda available to activate - aconda${NC}"
|
||||
|
||||
if [[ -n "$PS1" ]]; then
|
||||
green='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
echo -e "${green}[dotfiles] anaconda available to activate - aconda${NC}"
|
||||
fi
|
||||
|
||||
aconda() {
|
||||
export PATH="$HOME/anaconda3/bin:$PATH"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Editing
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export EDITOR='emacsclient -c --alternate-editor=vim'
|
||||
export VISUAL="$EDITOR"
|
||||
alias e="$EDITOR"
|
||||
alias e="\$EDITOR"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Files will be created with these permissions:
|
||||
# files 644 -rw-r--r-- (666 minus 022)
|
||||
# dirs 755 drwxr-xr-x (777 minus 022)
|
||||
|
@ -21,12 +23,3 @@ alias df="df -h"
|
|||
|
||||
# Recursively delete `.DS_Store` files
|
||||
alias dsstore="find . -name '*.DS_Store' -type f -ls -delete"
|
||||
|
||||
# Aliasing eachdir like this allows you to use aliases/functions as commands.
|
||||
alias eachdir=". eachdir"
|
||||
|
||||
# Create a new directory and enter it
|
||||
function md() {
|
||||
mkdir -p "$@" && cd "$@"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ -d "/opt/go" ]; then
|
||||
export PATH="/opt/go/bin:$PATH"
|
||||
fi
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
export GPG_TTY=$(tty)
|
||||
#!/usr/bin/env bash
|
||||
|
||||
GPG_TTY=$(tty)
|
||||
export GPG_TTY
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
if [[ ! -z "$PS1" ]]; then
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ -n "$PS1" ]]; then
|
||||
if command -v keychain &> /dev/null; then
|
||||
eval $(keychain --eval --agents ssh id_rsa id_ed25519)
|
||||
eval "$(keychain --eval --agents ssh id_rsa id_ed25519)"
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Prevent less from clearing the screen while still showing colors.
|
||||
export LESS=-XR
|
||||
|
||||
|
@ -7,9 +9,9 @@ function titlebar() {
|
|||
}
|
||||
|
||||
# SSH auto-completion based on entries in known_hosts.
|
||||
if [ ! -n "$ZSH" ]; then
|
||||
if [ -z "$ZSH" ]; then
|
||||
if [[ -e ~/.ssh/known_hosts ]]; then
|
||||
complete -o default -W "$(cat ~/.ssh/known_hosts | sed 's/[, ].*//' | sort | uniq | grep -v '[0-9]')" ssh scp sftp
|
||||
complete -o default -W "$(sed 's/[, ].*//' ~/.ssh/known_hosts | sort | uniq | grep -v '[0-9]')" ssh scp sftp
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
export NPM_PACKAGES="$HOME/.npm-packages"
|
||||
export PATH="$PATH:$HOME/.npm-packages/bin"
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ -d "${HOME}/perl5" ]; then
|
||||
export PERL5LIB="$HOME/perl5/lib/perl5"
|
||||
export PATH="$HOME/perl5/bin:$PATH"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
if [ ! -n "$ZSH" ]; then
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z "$ZSH" ]; then
|
||||
export PS1="\[\e[31m\]\u\[\e[33m\]@\[\e[34m\]\h\[\e[m\]:\[\e[35m\]\w\[\e[m\]\n\[\e[36m\]\@\[\e[m\] $ "
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pyenv
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -d "$HOME/.pyenv" ]; then
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# rbenv
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -d "$HOME/.rbenv" ]; then
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
alias sdf="mosh dctrud@iceland.sdf.org -- tmux a"
|
||||
alias sdfnew="mosh dctrud@iceland.sdf.org -- tmux"
|
||||
|
||||
alias club="mosh dctrud@tilde.club -- tmux a"
|
||||
alias clubnew="mosh dctrud@tilde.club -- tmux"
|
||||
|
||||
alias rr="mosh ubuntu@randomroad.net -- tmux a"
|
||||
alias rrnew="mosh ubuntu@petroc.randomroad.net -- tmux"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
alias sbuild="rm -rf builddir && ./mconfig -v && make -C builddir && sudo make -C builddir install"
|
||||
alias k="minikube kubectl -- "
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
rename 0.1.3
|
||||
Wednesday, Nov 4, 2009, 00:35
|
||||
Aristotle Pagaltzis
|
||||
http://plasmasturm.org/code/rename/
|
||||
|
||||
Note: downloaded directly because there's no repo to include.
|
|
@ -1,310 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
rename - renames multiple files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
F<rename>
|
||||
S<B<-h>>
|
||||
|
||||
F<rename>
|
||||
S<B<--man>>
|
||||
|
||||
F<rename>
|
||||
S<B<[ -0 ]>>
|
||||
S<B<[ -c ]>>
|
||||
S<B<[ -C ]>>
|
||||
S<B<[ -e code ]>>
|
||||
S<B<[ -f ]>>
|
||||
S<B<[ -i ]>>
|
||||
S<B<[ -l | -L ]>>
|
||||
S<B<[ -n ]>>
|
||||
S<B<[ -s from to ]>>
|
||||
S<B<[ -v ]>>
|
||||
S<B<[ files ]>>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<rename> renames the filenames supplied according to the rules specified. If a given filename is not modified, it will not be renamed. If no filenames are given on the command line, filenames will be read via standard input.
|
||||
|
||||
For example, to rename all files matching C<*.bak> to strip the extension, you might say
|
||||
|
||||
rename 's/\.bak$//' *.bak
|
||||
|
||||
If are confident that none of the filenames has C<.bak> anywhere else than at the end, you can also use the much easier typed
|
||||
|
||||
rename -s .bak '' *.bak
|
||||
|
||||
You can always do multiple changes in one ago:
|
||||
|
||||
rename -s .tgz .tar.gz -s .tbz2 .tar.bz2 *.tar.*
|
||||
|
||||
Note however that expressive options are order sensitive. The following would probably surprise you:
|
||||
|
||||
rename -s foo bar -s bar baz *
|
||||
|
||||
Since operations are cumulative, this would end up substituting (some of) the F<foo> matches in filenames with F<baz>! So pay attention to order. You may want to request a verbose dry run with C<-nv> for the first stab at a complex rename operation.
|
||||
|
||||
rename -nv -s bar baz -s foo bar *
|
||||
|
||||
You can combine the various expressive options to suit your needs. F.ex files from Microsoft(tm) Windows systems often have blanks and (sometimes nothing but) capital letters in their names. Let's say you have a bunch of such files to clean up, and you also want to move them to subdirectories based on extension. The following command should help, provided all directories already exist:
|
||||
|
||||
rename -cz -e '$_ = "$1/$_" if /(\..*)\z/' *
|
||||
|
||||
Again you need to pay attention to order sensitivity for expressive options. If you placed the C<-c> after the C<-e> in the above example, files with F<.zip> and F<.ZIP> extensions would be (attempted to be) moved to different directories because the directory name prefix would be added before the filenames were normalized. Once again, use verbose dry run requested using C<-nv> to get an idea of what exactly a complex rename operation is going to do.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-h>, B<--help>
|
||||
|
||||
See a synopsis.
|
||||
|
||||
=item B<--man>
|
||||
|
||||
Browse the manpage.
|
||||
|
||||
=back
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-0>, B<--null>
|
||||
|
||||
When reading file names from C<STDIN>, split on NUL bytes instead of newlines. This is useful in combination with GNU find's C<-print0> option, GNU grep's C<-Z> option, and GNU sort's C<-z> option, to name just a few. B<Only valid if no filenames have been given on the commandline.>
|
||||
|
||||
=item B<-c>, B<--lower-case>
|
||||
|
||||
Converts file names to all lower case.
|
||||
|
||||
=item B<-C>, B<--upper-case>
|
||||
|
||||
Converts file names to all upper case.
|
||||
|
||||
=item B<-e>, B<--expr>
|
||||
|
||||
The C<code> argument to this option should be a Perl expression that assumes the filename in the C<$_> variable and modifies it for the filenames to be renamed. When no other C<-c>, C<-C>, C<-e>, C<-s>, or C<-z> options are given, you can omit the C<-e> from infront of the code.
|
||||
|
||||
=item B<-g>, B<--glob>
|
||||
|
||||
Glob filename arguments. This is useful if you're using a braindead shell such as F<cmd.exe> which won't expand wildcards on behalf of the user.
|
||||
|
||||
=item B<-f>, B<--force>
|
||||
|
||||
Rename even when a file with the destination name already exists.
|
||||
|
||||
=item B<-i>, B<--interactive>
|
||||
|
||||
Ask the user to confirm every action before it is taken.
|
||||
|
||||
=item B<-k>, B<--backwards>, B<--reverse-order>
|
||||
|
||||
Process the list of files in reverse order, last file first. This prevents conflicts when renaming files to names which are currently taken but would be freed later during the process of renaming.
|
||||
|
||||
=item B<-l>, B<--symlink>
|
||||
|
||||
Create symlinks from the new names to the existing ones, instead of renaming the files. B<Cannot be used in conjunction with C<-L>.>
|
||||
|
||||
=item B<-L>, B<--hardlink>
|
||||
|
||||
Create hard links from the new names to the existing ones, instead of renaming the files. B<Cannot be used in conjunction with C<-l>.>
|
||||
|
||||
=item B<-n>, B<--dry-run>, B<--just-print>
|
||||
|
||||
Show how the files would be renamed, but don't actually do anything.
|
||||
|
||||
=item B<-s>, B<--subst>, B<--simple>
|
||||
|
||||
Perform a simple textual substitution of C<from> to C<to>. The C<from> and C<to> parameters must immediately follow the argument.
|
||||
|
||||
Quoting issues aside, this is equivalent to supplying a C<-e 's/\Qfrom/to/'>.
|
||||
|
||||
=item B<-v>, B<--verbose>
|
||||
|
||||
Print additional information about the operations (not) executed.
|
||||
|
||||
=item B<-z>, B<--sanitize>
|
||||
|
||||
Replaces consecutive blanks, shell meta characters, and control characters in filenames with underscores.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
mv(1), perl(1), find(1), grep(1), sort(1)
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None currently known.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Aristotle Pagaltzis
|
||||
|
||||
Idea, inspiration and original code from Larry Wall and Robin Barker.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
|
||||
use Pod::Usage;
|
||||
use Getopt::Long 2.24, qw(:config bundling no_ignore_case no_auto_abbrev);
|
||||
|
||||
use constant ERROR => do { bless \(my $l = 0), 'LOGLEVEL' };
|
||||
use constant INFO => do { bless \(my $l = 1), 'LOGLEVEL' };
|
||||
use constant DEBUG => do { bless \(my $l = 2), 'LOGLEVEL' };
|
||||
use constant VERB_FOR => {
|
||||
link => {
|
||||
inf => 'link',
|
||||
pastp => 'linked',
|
||||
exec => sub { link shift, shift or die },
|
||||
},
|
||||
symlink => {
|
||||
inf => 'symlink',
|
||||
pastp => 'symlinked',
|
||||
exec => sub { symlink shift, shift or die },
|
||||
},
|
||||
rename => {
|
||||
inf => 'rename',
|
||||
pastp => 'renamed',
|
||||
exec => sub { rename shift, shift or die },
|
||||
},
|
||||
};
|
||||
|
||||
sub argv_to_subst_expr {
|
||||
my $modifier = shift || '';
|
||||
pod2usage( -verbose => 1 ) if @ARGV < 2;
|
||||
my ($from, $to) = map quotemeta, splice @ARGV, 0, 2;
|
||||
# the ugly \${\""} construct is necessary because unknown backslash escapes are
|
||||
# not treated the same in pattern- vs doublequote-quoting context; only the
|
||||
# latter lets us do the right thing with problematic input like
|
||||
# ']{ool(haracter$' or maybe '>><//((/>'
|
||||
sprintf 's/\Q${\"%s"}/%s/%s', $from, $to, $modifier;
|
||||
}
|
||||
|
||||
my @EXPR;
|
||||
|
||||
GetOptions(
|
||||
'h|help' => sub { pod2usage( -verbose => 1 ) },
|
||||
'man' => sub { pod2usage( -verbose => 2 ) },
|
||||
'0|null' => \my $opt_null,
|
||||
'c|lower-case' => sub { push @EXPR, 's/([[:upper:]]+)/\L$1/g' },
|
||||
'C|upper-case' => sub { push @EXPR, 's/([[:lower:]]+)/\U$1/g' },
|
||||
'e|expr=s' => \@EXPR,
|
||||
'f|force' => \my $opt_force,
|
||||
'g|glob' => \my $opt_glob,
|
||||
'i|interactive' => \my $opt_interactive,
|
||||
'k|backwards|reverse-order' => \my $opt_backwards,
|
||||
'l|symlink' => \my $opt_symlink,
|
||||
'L|hardlink' => \my $opt_hardlink,
|
||||
'n|just-print|dry-run' => \my $opt_dryrun,
|
||||
'p|mkpath|make-dirs' => \my $opt_mkpath,
|
||||
'v|verbose+' => \(my $opt_verbose = 0),
|
||||
'z|sanitize' => sub { push @EXPR, 's/[!"\$&()=?`*\';<>|_[:cntrl:][:blank:]]+/_/g' },
|
||||
's|subst|simple' => sub { push @EXPR, argv_to_subst_expr },
|
||||
'S|subst-global' => sub { push @EXPR, argv_to_subst_expr('g') },
|
||||
) or pod2usage( -verbose => 1 );
|
||||
|
||||
die "TODO" if $opt_mkpath;
|
||||
|
||||
if(not @EXPR) {
|
||||
pod2usage( -verbose => 1 ) if not @ARGV or -e $ARGV[0];
|
||||
push @EXPR, shift;
|
||||
}
|
||||
|
||||
pod2usage( -verbose => 1 )
|
||||
if ($opt_hardlink and $opt_symlink)
|
||||
or ($opt_null and @ARGV);
|
||||
|
||||
++$opt_verbose if $opt_dryrun;
|
||||
|
||||
BEGIN {
|
||||
*CORE::GLOBAL::warn = sub {
|
||||
if(ref $_[0] eq 'LOGLEVEL') {
|
||||
my $msglevel = ${(shift)};
|
||||
print "@_\n" if $opt_verbose >= $msglevel;
|
||||
return;
|
||||
}
|
||||
warn @_;
|
||||
};
|
||||
}
|
||||
|
||||
my $code = do {
|
||||
my $cat = "sub { ".join('; ', @EXPR)." }";
|
||||
warn DEBUG, "Using expression: $cat";
|
||||
|
||||
my $evaled = eval $cat;
|
||||
die $@ if $@;
|
||||
die "Evaluation to subref failed. Check expression using -vn\n"
|
||||
unless 'CODE' eq ref $evaled;
|
||||
|
||||
$evaled;
|
||||
};
|
||||
|
||||
my $verb = VERB_FOR->{
|
||||
$opt_hardlink ? 'link' :
|
||||
$opt_symlink ? 'symlink' :
|
||||
do { 'rename' }
|
||||
};
|
||||
|
||||
if (!@ARGV) {
|
||||
warn INFO, "Reading filenames from STDIN";
|
||||
@ARGV = do {
|
||||
if($opt_null) {
|
||||
warn INFO, "Splitting on NUL bytes";
|
||||
local $/ = "\0";
|
||||
}
|
||||
<STDIN>;
|
||||
};
|
||||
chomp @ARGV;
|
||||
}
|
||||
|
||||
@ARGV = map glob, @ARGV if $opt_glob;
|
||||
|
||||
@ARGV = reverse @ARGV if $opt_backwards;
|
||||
|
||||
for (@ARGV) {
|
||||
my $old = $_;
|
||||
|
||||
$code->();
|
||||
|
||||
if($old eq $_) {
|
||||
warn DEBUG, "'$old' unchanged";
|
||||
next;
|
||||
}
|
||||
|
||||
if(!$opt_force and -e) {
|
||||
warn ERROR, "'$old' not $verb->{pastp}: '$_' already exists";
|
||||
next;
|
||||
}
|
||||
|
||||
if($opt_dryrun) {
|
||||
warn INFO, "'$old' would be $verb->{pastp} to '$_'";
|
||||
next;
|
||||
}
|
||||
|
||||
if($opt_interactive) {
|
||||
print "\u$verb->{inf} '$old' to '$_'? [n] ";
|
||||
if(<STDIN> !~ /^y(?:es)?$/i) {
|
||||
warn DEBUG, "Skipping '$old'.";
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
eval { $verb->{exec}($old, $_) };
|
||||
|
||||
if($@) {
|
||||
warn ERROR, "Can't $verb->{inf} '$old' to '$_': $!";
|
||||
next;
|
||||
}
|
||||
|
||||
warn INFO, "'$old' $verb->{pastp} to '$_'";
|
||||
}
|
Loading…
Reference in New Issue