0

I'm dealing with a rather peculiar issue. I want to catch all file names in a directory that contain a range of numbers. The directory has the following files

run_1_500ns.root
run_2_500ns.root
run_3_500ns.root
run_4_500ns.root
run_5_500ns.root
...
run_55000_500ns.root

For instance I want to get the files run_600_500ns.root and run_601_500ns.root and feed them in the hadd command (that's a command from the ROOT/cern data analysis software).

If I run the following command on a terminal I get the filename that I'm looking for.

$ filename=`find . -name "*_600_*.root" | sed 's#.*/##'`
$ echo filename
run_600_500ns.root

However, if I run the following script, I get all files in the directory. This script used to work on redHat 6 but at the moment I'm using Ubuntu 18.04. Not sure if that's the issue, but it's the only (big) change in my setup. Any idea on what might be the issue?

#!/bin/bash
# A script to add root files using hadd command
# NOT idiot proof

#variables
CURRENT_DIR=$(pwd)


echo

if [ "$#" -eq 4 ]; then
    
    #input arguments
    OUT_ROOT=$(readlink -f $1)
    FILES_DIR=$(readlink -f $2)
    FIRST_RUN=$3
    LAST_RUN=$4
    
    echo
    echo "Output file : $OUT_ROOT"
    echo "Input files : $FILES_DIR"
    echo
    
    cd $FILES_DIR
    
    #source_root_files="*"`seq -s "*.root *" $FIRST_RUN $LAST_RUN`"*.root"
    source_root_files=""    
    filename=""
    
    for i in $(seq $FIRST_RUN $LAST_RUN); do
        filename=$(find . -name "*_$i_*.root" | sed 's#.*/##')
        source_root_files="$source_root_files $filename"
    done

    
    echo "Merging root files"
    hadd -f6 $OUT_ROOT $source_root_files
    
    cd $CURRENT_DIR
else
    echo "Provide the correct number of arguments"
    echo "Usage   : radd.sh <output root file> <input root file directory> <first run> <last run>"
fi

Running the script as sh -x script.sh 2> log.log gives me the following

+ pwd
+ CURRENT_DIR=current_directory
+ echo
+ [ 4 -eq 4 ]
+ readlink -f test.root
+ OUT_ROOT=current_directory/test.root
+ readlink -f .
+ FILES_DIR=current_directory
+ FIRST_RUN=600
+ LAST_RUN=601
+ echo
+ echo Output file : current_directory/test.root
+ echo Input files : current_directory
+ echo
+ cd current_directory
+ source_root_files=
+ filename=
+ seq 600 601
+ find . -name *_*.root
+ sed s#.*/##
+ filename=S0Test_51686_500ns_CW_0ns_CBT_0ns_DEBT.root
Thanos
  • 594
  • 2
  • 7
  • 28
  • 3
    Your script doesn't pass https://www.shellcheck.net/ – Gilles Quénot Nov 29 '22 at 19:35
  • Add `set -x` at the beginning to get an execution trace and see what's going wrong. – Gordon Davisson Nov 29 '22 at 19:38
  • @GillesQuenot Yes, I saw. It's weird... It evens complains about `cd` – Thanos Nov 29 '22 at 19:49
  • @GordonDavisson I did that and it seems the filename isn't parsed correctly and I don't know why. See updated question – Thanos Nov 29 '22 at 19:51
  • 1
    @Thanos: personally, I will not help here, there's too much to say. If you update your code to pass shellcheck, you will have more help. The most important is the need to quote "$variables". Learn how to quote properly in shell, it's very important : > "Double quote" every literal that contains spaces/metacharacters and _every_ expansion: `"$var"`, `"$(command "$var")"`, `"${array[@]}"`, `"a & b"`. Use `'single quotes'` for code or literal `$'s: 'Costs $5 US'`, `ssh host 'echo "$HOSTNAME"'`. See – Gilles Quénot Nov 29 '22 at 19:59
  • @GillesQuenot Hard to pass spellcheck. Thanks for your time ans study material though! – Thanos Nov 29 '22 at 20:56
  • Start by quoting your variables. – dan Nov 29 '22 at 21:28
  • shellcheck shows the problem clearly: in `"*_$i_*.root"`, it's treating `$i_` as the variable reference, not just `$i`. To disambiguate it, use `"*_${i}_*.root"`. I have no idea how this could've worked on RH6, since the way it's parsing it should be the same under any Bourne-family shell. I'd also recommend fixing everything else shellcheck points out, except for double-quoting `$source_root_files` in the `hadd` command -- in that case, your script *depends on* word splitting. As for why `cd` should be checked, see [this sad story](https://apple.stackexchange.com/questions/378942). – Gordon Davisson Nov 29 '22 at 21:31
  • @GordonDavisson Thanks for your help! If I `echo $i` I get exactly what I want so I'm confused about having to use `${i}` – Thanos Nov 30 '22 at 16:13
  • @Thanos Variable name parsing after `$` is greedy -- if characters *could* be part of the variable name, then it assumes they *are* part of the variable name, and `_` *can* be part of a variable name. See ['How to echo "$x_$y" in Bash script?'](https://stackoverflow.com/questions/14390955/how-to-echo-x-y-in-bash-script) and Giles' answer to ["$VAR vs ${VAR} and to quote or not to quote"](https://unix.stackexchange.com/questions/4899/var-vs-var-and-to-quote-or-not-to-quote). – Gordon Davisson Nov 30 '22 at 17:26

0 Answers0