[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Using PE to specify an array
From: |
Bruce Hohl |
Subject: |
Re: [Help-bash] Using PE to specify an array |
Date: |
Mon, 17 Sep 2018 11:36:25 -0400 |
@Greg, it is an interesting happen-stance that you replied as my question
arose from my pass at completing your duplicate file finder "exercise" at
mywiki.wooledge.org/BashProgramming/04: "If you want to "fix" this
"problem", you might suppress all the printing until the end, and then
iterate over the whole array and print only those values that contain a
newline. (This is left as an exercise.)" So with your suggestion to use
nameref vars the following seems to work:
=== Duplicate file finder exercise === (NO comments)
#!/bin/bash
while read -r md5_hash file; do
var_hash=md5_$md5_hash
declare -n ind_var_hash=$var_hash
[[ address@hidden -eq 1 ]] && declare -a dup_array+="($var_hash)"
declare -a ${!ind_var_hash}+="('$file')"
done < <(find "${1:-.}" -name $'*\n*' -prune -o -type f -exec md5sum {} +)
declare -n e
for e in address@hidden; do
echo ${!e}
for f in address@hidden; do echo " $f"; done
done
=== Duplicate file finder exercise === (WITH comments):
#!/bin/bash
# Usage: finddups [directory]
# If no directory is specified, start in .
# This script uses Linux-specific md5sum
# and bash 4.X nameref
while read -r md5_hash file; do
var_hash=md5_$md5_hash
# prefix hash so the string does not begin
# with a numeric (not allowed as var name)
declare -n ind_var_hash=$var_hash
# use nameref var here & below to avoid substitution errors
# that occur with attempts at nested parameter expansion
[[ address@hidden -eq 1 ]] && declare -a dup_array+="($var_hash)"
# if array ind_var_hash has a second element (from a prior iteration)
# then there is at least one 1 duplicate of the file, thus add
$var_hash
# to dup_array
declare -a ${!ind_var_hash}+="('$file')"
# declare/add $file to related $var_hash array, regarding "('$file')"
# outside quotes required else assignment fails with syntax error
# inside single quotes suppress word splitting
done < <(find "${1:-.}" -name $'*\n*' -prune -o -type f -exec md5sum {} +)
declare -n e
for e in address@hidden; do
echo ${!e}
for f in address@hidden; do echo " $f"; done
done
# 'declare -n e' -n assigns the bash nameref attribute to var e
# see man page regarding effect within a for loop
Thanks for your reply & I definitely appreciate your wiki.
It's been very helpful for improving my understanding of bash.
On Fri, Sep 14, 2018 at 11:06 AM Jesse Hathaway <address@hidden>
wrote:
> On Fri, Sep 14, 2018 at 7:34 AM Bruce Hohl <address@hidden> wrote:
> > # I DID EXPECT THIS TO WORK as it seems to expand as desired.
> > $ _$var1+="(789)"
> > bash: _ugly_hash+=(789): command not found
>
> eval is a possible option
>
> eval "_${var1}+=(789)"
>
> unless there is a more idiomatic way of having bash perform the
> interpolation on the variable name.
>
Re: [Help-bash] Using PE to specify an array, Greg Wooledge, 2018/09/14