From 335b71e1a32629a461b224075a4d83a19dd376cb Mon Sep 17 00:00:00 2001 From: Steven Baltakatei Sandoval Date: Tue, 17 Jan 2023 06:43:54 +0000 Subject: [PATCH 1/1] feat(user/bkfeh):Process stdin and psargs separately - Note: Filter out dotfiles via a grep of file list --- unitproc/bkt-read_psarg | 36 +++++++++++++ unitproc/bkt-read_stdin | 36 +++++++++++++ user/bkfeh | 110 +++++++++++++++++++++++++++------------- 3 files changed, 147 insertions(+), 35 deletions(-) create mode 100644 unitproc/bkt-read_psarg create mode 100644 unitproc/bkt-read_stdin diff --git a/unitproc/bkt-read_psarg b/unitproc/bkt-read_psarg new file mode 100644 index 0000000..0e583eb --- /dev/null +++ b/unitproc/bkt-read_psarg @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Desc: Reads positional arguments + +yell() { echo "$0: $*" >&2; } # print script path and all args to stderr +die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status +must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails +read_psarg() { + # Desc: Reads arguments; outputs as stdout lines + # Input: args + # Output: stdout (newline delimited) + # Example: read_psarg "$@" + # Depends: GNU bash (version 5.1.16) + # Version: 0.0.1 + local input_psarg output; + + # Store arguments + if [[ $# -gt 0 ]]; then + input_psarg="$*"; + fi; + + # Store as output array elements + ## Read in positional arguments + if [[ -n $input_psarg ]]; then + for arg in "$@"; do + output+=("$arg"); + done; + fi; + + # Print to stdout + printf "%s\n" "${output[@]}"; +}; # read positional argument to stdout lines +main() { + read_psarg "$@"; +}; + +main "$@"; diff --git a/unitproc/bkt-read_stdin b/unitproc/bkt-read_stdin new file mode 100644 index 0000000..31469b3 --- /dev/null +++ b/unitproc/bkt-read_stdin @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Desc: Reads stdin + +yell() { echo "$0: $*" >&2; } # print script path and all args to stderr +die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status +must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails +read_stdin() { + # Desc: Consumes stdin; outputs as stdout lines + # Input: stdin (consumes) + # Output: stdout (newline delimited) + # Example: printf "foo\nbar\n" | read_stdin + # Depends: GNU bash (version 5.1.16) + # Version: 0.0.1 + local input_stdin output; + + # Store stdin + if [[ -p /dev/stdin ]]; then + input_stdin="$(cat -)"; + fi; + + # Store as output array elements + ## Read in stdin + if [[ -n $input_stdin ]]; then + while read -r line; do + output+=("$line"); + done < <(printf "%s\n" "$input_stdin"); + fi; + + # Print to stdout + printf "%s\n" "${output[@]}"; +}; # read stdin to stdout lines +main() { + read_stdin "$@"; +}; + +main "$@"; diff --git a/user/bkfeh b/user/bkfeh index d2f5423..7dbf9fb 100755 --- a/user/bkfeh +++ b/user/bkfeh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Version: 0.0.5 +# Version: 0.0.7 # Ref/Attrib: [1] Tange, Ole. GNU Parallel with Bash Array. 2019-03-24. https://unix.stackexchange.com/a/508365/411854 # Depends: GNU Parallel, GNU Bash v5.1.16, feh 3.6.3 @@ -155,33 +155,46 @@ check_depends() { if ! checkapp feh parallel; then displayMissing; die "FATAL:Missing apps."; fi; return 1; }; # check dependencies -read_stdin_psarg() { - # Desc: Consumes stdin and reads arguments; outputs as stdout lines +read_stdin() { + # Desc: Consumes stdin; outputs as stdout lines # Input: stdin (consumes) - # Input: args # Output: stdout (newline delimited) - # Example: read_stdin_psarg "$@" + # Example: printf "foo\nbar\n" | read_stdin # Depends: GNU bash (version 5.1.16) - # Version: 0.0.3 - local input_stdin input_psarg output; + # Version: 0.0.1 + local input_stdin output; # Store stdin if [[ -p /dev/stdin ]]; then input_stdin="$(cat -)"; - fi; + fi; - # Store arguments - if [[ $# -gt 0 ]]; then - input_psarg="$*"; - fi; - - # Combine as output array elements + # Store as output array elements ## Read in stdin if [[ -n $input_stdin ]]; then while read -r line; do output+=("$line"); done < <(printf "%s\n" "$input_stdin"); fi; + + # Print to stdout + printf "%s\n" "${output[@]}"; +}; # read stdin to stdout lines +read_psarg() { + # Desc: Reads arguments; outputs as stdout lines + # Input: args + # Output: stdout (newline delimited) + # Example: read_psarg "$@" + # Depends: GNU bash (version 5.1.16) + # Version: 0.0.1 + local input_psarg output; + + # Store arguments + if [[ $# -gt 0 ]]; then + input_psarg="$*"; + fi; + + # Store as output array elements ## Read in positional arguments if [[ -n $input_psarg ]]; then for arg in "$@"; do @@ -191,33 +204,26 @@ read_stdin_psarg() { # Print to stdout printf "%s\n" "${output[@]}"; -}; # read stdin and positional argument to stdout lines -print_filelist() { +}; # read positional argument to stdout lines +find_flist() { # Desc: print file list to stdout via `find` using script parameters # Input: arg1: path to dir # var: find_depth # var: pattern_find_iregex # var: find_size if [[ ! -d "$1" ]]; then return 1; fi; - must find "$1" -maxdepth "$find_depth" -type f -iregex "$pattern_find_iregex" -size +"$find_size"; + must find "$1" -maxdepth "$fdepth" -type f -iregex "$firegex" -size +"$fsize"; }; # print file list to stdout from dir with script parameters main() { # Depends: read_stdin_psarg() v0.0.1, check_depends() local re_dotfile; - declare -a main_dirs; + declare -a dirs_stdin dirs_psarg; declare -a paths_images; declare list_paths_images; check_depends; - # Find settings - find_depth=10; # default: 10 - find_size="10k"; # default: minimum "10k" - #Find files ending in .jpg, .gif, etc. - pattern_find_iregex=".+\(jpg\|jpeg\|gif\|png\|webm\)$"; # update according to `find . -type f | grep -Eo "\.([[:alnum:]])+$" | sort -u` - export find_depth find_size pattern_find_iregex; # export for parallel - - #Populate main_dirs array - ## Read stdin and positional arguments as lines + #Populate dirs_stdin and dirs_psarg arrays + ## Read stdin as lines re_dotfile="^\."; # first char is a dot while read -r line; do # Check if dir @@ -231,15 +237,46 @@ main() { echo "ERROR:Is a dotdir:$line" 1>&2; continue fi; - main_dirs+=("$line"); - done < <(read_stdin_psarg "$@"); - - # Catch empty main_dirs array - if [[ "${#main_dirs[@]}" -le 0 ]]; then die "FATAL:No valid directories provided."; fi; + dirs_stdin+=("$line"); + done < <(read_stdin); + ## Read positional arguments as lines + re_dotfile="^\."; # first char is a dot + while read -r line; do + # Check if dir + if [[ ! -d "$line" ]]; then + echo "ERROR:Not a dir:$line" 1>&2; + continue; + fi; + dir_name="$(basename "$line")"; + # Exclude dotdirs + if [[ "$dir_name" =~ $re_dotfile ]]; then + echo "ERROR:Is a dotdir:$line" 1>&2; + continue + fi; + dirs_psarg+=("$line"); + done < <(read_psarg "$@"); + + # Catch all arrays empty + if [[ "${#dirs_stdin[@]}" -le 0 ]] && [[ "${#dirs_psarg[@]}" -le 0 ]]; then + die "FATAL:No valid directories provided."; + fi; # Generate file list - paths_images+=("$( parallel print_filelist {} ::: "${main_dirs[@]}" )"); # See [1] - + # Find settings + firegex=".+\(jpg\|jpeg\|gif\|png\|webm\)$"; # update according to `find . -type f | grep -Eo "\.([[:alnum:]])+$" | sort -u` + fsize="10k"; # default: minimum "10k" + export firegex fsize ; # export for parallel + ## Call find_filelist() in parallel for positional argument input + if [[ "${#dirs_psarg[@]}" -gt 0 ]]; then + fdepth=10; export fdepth; # 10 for dirs from positional arguments + paths_images+=("$( parallel find_flist {} "$fdepth" "$firegex" "$fsize" ::: "${dirs_psarg[@]}" )"); # See [1] + fi; + ## Call find_filelist() in parallel for stdin input + if [[ "${#dirs_stdin[@]}" -gt 0 ]]; then + fdepth=1; export fdepth; # 1 ofr dirs from stdin + paths_images+=("$( parallel find_flist {} "$fdepth" "$firegex" "$fsize" ::: "${dirs_stdin[@]}" )"); # See [1] + fi; + # Convert paths_images array into file list for i in "${!paths_images[@]}"; do list_paths_images="$(printf "%s\n%s" "${paths_images[$i]}" "$list_paths_images")"; @@ -252,6 +289,9 @@ main() { # Sort, remove duplicate paths list_paths_images="$(echo "$list_paths_images" | sort -u | tr -s '\n')"; + # Remove paths with dotfiles + list_paths_images="$(echo "$list_paths_images" | grep -viE "/\." )"; + # Write list_paths_images_tmp="/dev/shm/$(date +%Y%m%dT%H%M%S.%N%z)"..feh_paths.txt; must echo -n "$list_paths_images" > "$list_paths_images_tmp"; @@ -265,7 +305,7 @@ main() { # Cleanup must rm "$list_paths_images_tmp"; }; -export -f yell die must read_stdin_psarg print_filelist; +export -f yell die must read_stdin read_psarg find_flist; #==END Define local functions== main "$@"; -- 2.30.2