Last active
July 15, 2020 21:44
-
-
Save h8rt3rmin8r/fe5793bb8d35bbc9e3a3ff6de83e84fa to your computer and use it in GitHub Desktop.
Clean up the Ubuntu system screenshots from ~/Pictures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env bash | |
#>------------------------------------------------------------------------------ | |
#> | |
#> [ screenshot_clean.sh ] | |
#> | |
#> About: | |
#> | |
#> Clean up the Ubuntu system screenshots from ~/Pictures | |
#> | |
#> All screenshots are renamed and moved into a new directory located at | |
#> ~/Pictures/Screenshots. The new file names are automatically derived and | |
#> use the following schema: | |
#> | |
#> <UNIX_TIME>-<YYmmddHHMMSS>.png | |
#> | |
#> Consider auto-execution via cron (configurations for 'crontab -e'): | |
#> | |
#> ## Daily at midnight: | |
#> 0 0 * * * /usr/local/bin/screenshot_clean.sh | |
#> | |
#> ## Weekly on Monday at midnight: | |
#> 0 0 * * 1 /usr/local/bin/screenshot_clean.sh | |
#> | |
#> Screenshots can be similarly archived from alternative directory locations | |
#> in the manner described below in the "Usage" section. | |
#> | |
#> Usage: | |
#> | |
#> screenshot_clean.sh <DIRECTORY> | |
#> screenshot_clean.sh <OPTION> | |
#> | |
#> where "DIRECTORY" is a valid directory reference; and where "OPTION" is | |
#> one of the following: | |
#> | |
#> | | |
#> -h, --help | Print this help text to the terminal | |
#> | | |
#> | |
#> NOTE: No inputs are required when executing this script. If no alternative | |
#> directory is passed, this script will automatically execute on the files | |
#> found in the ~/Pictures directory. | |
#> | |
#> Attribution: | |
#> | |
#> Created on 20200715 by h8rt3rmin8r ([email protected]) | |
#> | |
#> Source: | |
#> | |
#> https://pastebin.com/YAUbYGFd | |
#> https://gist.github.com/h8rt3rmin8r/fe5793bb8d35bbc9e3a3ff6de83e84fa | |
#> | |
#>------------------------------------------------------------------------------ | |
# Declare functions | |
function sc_datemod() { | |
# Date transformation function (date stamp into UNIX timestamp conversion) | |
local i_all="$@" | |
local out_len=10 | |
if [[ "${#i_all}" -lt 8 || "${i_all}" =~ [^0-9] ]]; then | |
return 1 | |
fi | |
local i_all_a=${i_all:0:8} | |
local i_all_b=${i_all#$i_all_a} | |
case "$(printf '%s' ${i_all_b} | wc -c)" in | |
1|3|5) | |
return 1 | |
;; | |
0) | |
local i_time="00:00:00" | |
;; | |
2) | |
local i_time="${i_all_b}:00:00" | |
;; | |
4) | |
local i_time="${i_all_b:0:2}:${i_all_b: -2}:00" | |
;; | |
6) | |
local i_hour=${i_all_b:0:2} | |
local i_minute_pre=${i_all_b#$i_hour} | |
local i_minute=${i_minute_pre:0:2} | |
local i_second=${i_all_b: -2} | |
local i_time="${i_hour}:${i_minute}:${i_second}" | |
;; | |
7|8|9|10|11|12|13|14|15|16|17|18|19|20) | |
local i_hour=${i_all_b:0:2} | |
local i_minute_pre=${i_all_b:0:4} | |
local i_minute=${i_minute_pre: -2} | |
local i_second_pre=${i_all_b:0:6} | |
local i_second="${i_second_pre: -2}.${i_all_b:6}" | |
local i_time="${i_hour}:${i_minute}:${i_second}" | |
;; | |
esac | |
local i_year=${i_all_a:0:4} | |
local i_month_pre=${i_all_a:0:6} | |
local i_month=${i_month_pre: -2} | |
local i_day=${i_all_a: -2} | |
local in_x="${i_year}-${i_month}-${i_day} ${i_time}" | |
local output_prime=$(date -d "${in_x}" '+%s%N' 2>/dev/null) | |
local e_c=$(date -d "${in_x}" '+%s%N' &>/dev/null; echo "$?") | |
local output=${output_prime:0:$out_len} | |
echo "${output}" | |
return ${e_c} | |
} | |
function sc_help() { | |
# Script help text printing function | |
cat "${0}" \ | |
| grep -E '^#[>]' \ | |
| sed 's/^..//' | |
return $? | |
} | |
function sc_l2a() { | |
# File-lines-to-array conversion function | |
if [[ -t 0 ]]; then | |
if [[ "x${1}" == "x" ]]; then | |
return 1 | |
fi | |
if [[ -f "${1}" ]]; then | |
mapfile -t L_ARR <"${1}" | |
else | |
return 1 | |
fi | |
else | |
return 1 | |
fi | |
export L_ARR | |
return $? | |
} | |
function sc_ls() { | |
# Screenshot file listing function | |
ls -CF "${t_d}" \ | |
| tr '\t' '\n' \ | |
| sed 's/\ \{2\}/\n/g' \ | |
| sed '/^[ ]*$/d' \ | |
| sed 's/^\ *//' \ | |
| sed 's/[*@]$//' \ | |
| sed '/[/]/d' \ | |
| LC_ALL=C sort \ | |
| grep -E '^S([cehnorst]){9}.from.([12][0-9][0-9][0-9])-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]) (0[0-9]|1[0-9]|2[0-3])-([0-5][0-9])-([0-5][0-9])\.png' | |
return $? | |
} | |
function sc_vb() { | |
# Script verbosity printing function | |
local runtime=$(date '+%s%N') | |
local sh_name="${s_h}" | |
local i_n="$@" | |
echo "${runtime}|${sh_name}|${i_n}" &>/dev/stderr | |
return $? | |
} | |
# Declare variables and arrays, then execute operations | |
_q1=$'\u0027' | |
_q2=$'\u0022' | |
_pa=$'\u0028' | |
_pb=$'\u0029' | |
_sp=$'\u0020' | |
_usd=$'\u0024' | |
s_h_pre="${0//*\/}" | |
s_h="${s_h_pre%[.]sh}" | |
r_t="$(date '+%s%N')" | |
n_c="${RANDOM:0:1}${RANDOM: -1}${RANDOM: -1}${RANDOM: -1}${RANDOM: -1}" | |
t_h="${HOME}" | |
t_d="${t_h}/Pictures" | |
o_d="${t_d}/Screenshots" | |
tmpf="/tmp/${s_h}_${r_t}-${n_c}" | |
declare -a sc_source=() | |
declare -a sc_outmod=() | |
declare -a sc_output=() | |
## Catch help text requests | |
if [[ "${1}" == "-h" || "${1}" =~ ^[-]+help$ ]]; then | |
sc_help | |
exit $? | |
fi | |
## Catch alternative target directory references | |
if [[ ! "x${1}" == "x" ]]; then | |
if [[ -d "${1}" ]]; then | |
t_d=$(readlink -f "${1}") | |
else | |
sc_vb "ERROR: Input is not a valid directory reference: ${1}" | |
sc_vb "Use '--help' for more information" | |
exit 1 | |
fi | |
fi | |
## Make the temp file | |
touch "${tmpf}" | |
## Store a list of valid screenshot images in the temp file | |
sc_ls >> "${tmpf}" | |
## Consume the lines of the temp file into an array, "L_ARR" | |
sc_l2a "${tmpf}" | |
## Kill the script if the "L_ARR" array has no elements | |
if [[ "${#L_ARR[@]}" -lt 1 ]]; then | |
sc_vb "ERROR: No valid screenshots were found" | |
rm "${tmpf}" &>/dev/null | |
unset L_ARR | |
unset sc_source | |
unset sc_outmod | |
unset sc_output | |
unset sc_sequence | |
exit 1 | |
fi | |
## Loop through the discovered screenshot file names and generate three arrays | |
## | |
## 1) sc_source ==> same as "L_ARR" | |
## 2) sc_output ==> second half of the pending output file names | |
## 3) sc_outmod ==> date strings to be transformed in the following loop | |
## | |
for i in "${L_ARR[@]}"; do | |
sc_vb "Processing: ${i}" | |
ca_src="${i}" | |
ca_out=$(sed 's/^.*from\ //' <<<"${ca_src}" | tr -d ' ' | tr -d '-') | |
ca_mod=$(cut -d '.' -f1 <<<"${ca_out}") | |
sc_source+=( "${ca_src}" ) | |
sc_output+=( "${ca_out}" ) | |
sc_outmod+=( "${ca_mod}" ) | |
done | |
## Set variables and arrays required by the second loop processes | |
sc_count="${#sc_source[@]}" | |
let sc_count=sc_count-1 | |
declare -a sc_sequence=( $(seq 0 1 ${sc_count}) ) | |
## Clear out the temp file so it can be used as a parallel command file | |
echo -n > "${tmpf}" | |
for i in "${sc_sequence[@]}"; do | |
## Derive the parallel commands | |
cb_src="${sc_source[$i]}" | |
cb_mod_pre="${sc_outmod[$i]}" | |
cb_mod=$(sc_datemod "${cb_mod_pre}") | |
cb_out="${sc_output[$i]}" | |
cb_a="${t_d}/${cb_src}" | |
cb_b="${o_d}/${cb_mod}-${cb_out}" | |
str_a="mv ${_q2}${cb_a}${_q2} ${_q2}${cb_b}${_q2};" | |
str_b_a="echo ${_q2}${_usd}${_pa}date ${_q1}+%s%N${_q1}${_pb}" | |
str_b_b="|${s_h}|Complete: ${cb_a} ==> ${cb_b}${_q2}" | |
str_b="${str_b_a}${str_b_b}" | |
## Write the parallel commands into the temp file | |
echo "${str_a} ${str_b}" >> "${tmpf}" | |
done | |
## Make sure the output directory exists | |
mkdir -p "${o_d}" | |
## Perform the file moving and renaming process using GNU Parallel | |
parallel --no-notice -k :::: "${tmpf}" 2>/dev/null | |
## Capture the exit code from the moving processes | |
e_c="$?" | |
## | |
## If the exit code was bad, inform the user that parallel should be installed | |
## if parallel cannot be found on the system; otherwise let the user know that | |
## something went wrong | |
## | |
if [[ "${e_c}" -ne 0 ]]; then | |
sc_vb "ERROR: Missing required software 'parallel'" | |
sc_vb "Install 'parallel' with: 'sudo apt-get install parallel' and try again" | |
fi | |
## Clean up the workspace (destroy the temp file and unset all arrays) | |
rm "${tmpf}" &>/dev/null | |
unset L_ARR | |
unset sc_source | |
unset sc_outmod | |
unset sc_output | |
unset sc_sequence | |
exit ${e_c} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment