Since the right side of a |
pipe is a sub-shell, it can not persist or update a variable. It is not possible to use a counter in a variable like you do.
Fortunately Bash allow you to reverse the operation and feed the main shell (here a while
loop) with the output of a command running in a sub-shell.
Since we update our variables within the main shell, it works like that:
#!/usr/bin/env bash
group=1 # Group counter
files_per_group=4 # How many files per group
filescount=0 # Files counter
newline='' # Newline code used between groups
# loop reading all null delimited files names returned by find -print0
while read -d '' -r file; do
# If count of file is a multiple of files per group, then start a new group
if [ $((filescount % files_per_group)) -eq 0 ]; then
printf '%sGroup %d:' "$newline" "$group"
# Increment group counter for upcoming group
group=$((group + 1))
newline=$'\n' # To separate next group in another line
fi
# Print space delimited file-name
printf ' %s' "$file"
# Increment the files counter
filescount=$((filescount + 1))
done < <(
# feed the whole while loop with the output of find
find cobacoba -type f -print0
)
echo
Solution with building parameters to call a bash script:
#!/usr/bin/env bash
# Dummy bashscript as a function to test call with parameters
bashscript() {
printf 'Called bashscript.sh\n'
printf 'group %s\n' "$1"
shift
printf '%d files:\n' "$#"
printf ' %s' "$@"
printf $'\n\n'
}
group=1 # Group counter
files_per_group=5 # How many files per group
filescount=0 # Files counter
bashscriptparams=() # Arguments for the bash scripts
# loop reading all null delimited files names returned by find -print0
while read -d '' -r file; do
# If count of file is a multiple of files per group, then start a new group
if [ $((filescount % files_per_group)) -eq 0 ]; then
#printf '%sGroup %d:' "$newline" "$group"
# Set the group number as first param of the bash script
bashscriptparams=("$group")
# Increment group counter for upcoming group
((group++))
fi
# Add the file as next parameter of the bash script
bashscriptparams+=("$file")
# Print space delimited file-name
#printf ' %s' "$file"
# If last file of group, then group is complete
if [ $((filescount % files_per_group)) -eq $((files_per_group - 1)) ]; then
# Launch the bash script with its arguments (group file_1 .. file_n)
bashscript "${bashscriptparams[@]}"
fi
# Increment the files counter
((filescount++))
done < <(
# feed the whole while loop with the output of find
find cobacoba -type f -print0
)
# If we reach here with an incomplete files group
if [ $((filescount % files_per_group)) -le $((files_per_group - 1)) ]; then
# Launch the bash script with its incomplete files arguments (group file_1 .. file_n)
bashscript "${bashscriptparams[@]}"
fi
Output:
Called bashscript.sh
group 1
5 files:
cobacoba/1.q2 cobacoba/1.3 cobacoba/1.1 cobacoba/1.5 cobacoba/1.6
Called bashscript.sh
group 2
4 files:
cobacoba/1.2 cobacoba/1.4 cobacoba/1.q cobacoba/1.q23