since bash doesn't have the equivalent of
zsh's(N)glob qualifier or ksh93's~(N)glob operator, before using a glob in a for loop (at least), you need to set thenullgloboption:shopt -s nullglob for infile in *_1.fastq.Block*; do...If you don't and there's no matching file, you'll loop over a literal
*_1.fastq.Block*You can set IFS for
readonly with:IFS=_ read -ra ADDR <<< "$infile"(see also the quotes around$infilewhich are needed in older versions ofbash). That way,$IFSis only changed whilereadruns¹ and it's restored to its previous value afterreadreturns.IFS=. read -ra <<< "$var"is a poor method for splitting. First is only works for single line$vars which is not necessarily the case of file names, and also it's quite inefficient. That involves either storing the contents of$varinto a tempfile or feed it via a pipe depending on the version ofbashand/or the size of$varand then reading it one byte at a time until a newline is found.Here, you could use the split+glob operator instead:
IFS=:; set -o noglob addr=( $infile )(or
addr=( $infile'' )to not ignore a trailing:.)Or switch to better shells with proper splitting operators.
Another approach here, you would be to do:
regex='^(.*)_1\.fastq\.(Block.*)$' if [[ $infile =~ $regex ]]; then outfile=${BASH_REMATCH[1]}_2.fastq.${BASH_REMATCH[2]} ...With the caveat that regex matching only works with valid text, which again is not a guarantee for file names.
Here, you could also use standard
shparameter expansion operators:new_file=${infile%_1.fastq.Block*}_2.fastq.Block${infile##*_1.fastq.Block}Or the ksh93-style:
new_file=${infile/_1.fastq.Block/_2.fastq.Block}(note the variations in behaviour among all those approaches if
_1.fastq.Blockoccurs more than once in the file name).