0

I extracted the paths for files using find. The command to find paths is as follows:

tmp=$(find $Some_Dir -name "*.gz")

The output is:

echo "$tmp"

/xxxx/abc/bcd/def/something/ZRT834/ZRT834_9/5678/S1_L001_R1.gz /xx/abc/bcd/def/ddd/ZRT834/ZRT834_9/5678/S2_L001_I1.gz /abc/bcd/def/ZRT834/ZRT834_9/5678/S1_L001_I2.gz /abc/bcd/def/ZRT207/ZRT207_1/5678/S1_L001_R1.gz /abc/bcd/def/hfgdh/ZRT207/ZRT207_1/5678/S1_L001_R2.gz /abc/bcd/def/ZRT207/ZRT207_1/5678/S1_L001_I2.gz /sgdj/hbsdj/ldnc/jnjdss/ZRT102_9/S5_L002_I1.gz

I want to create a sub-directory based on matching pattern and create symbolic links. For example, I want to match the pattern starting with ZRT and ending with _somenumber in each path and create sub-directory with that path element if it doesn't exist. Then create symbolic links of the .gz files into their respective directories.

The output needs to be: ZRT834_9 directory with symbolic links of S1_L001_R1.gz, S2_L001_I1.gz, and S1_L001_I2.gz and so on.

Edit: This was my original question. Also, I had posted a less complex question earlier here.

2
  • I had posted that question earlier. But, based on a few member's suggestions, I had posted this question to specifically address my issue.
    – botloggy
    Commented Sep 15, 2021 at 10:24
  • ok, sorry, i misunderstood.
    – pLumo
    Commented Sep 15, 2021 at 10:35

2 Answers 2

1

Regarding tmp=$(find $Some_Dir -name "*.gz"):

  1. Always quote your shell variables, i.e. "$Some_Dir", not just $Some_Dir, see https://mywiki.wooledge.org/Quotes.
  2. Don't read file names into a scalar variable as it becomes much harder to deal with spaces in file names if you do, read them into an array.

so that should be:

readarray -d '' files < <(find "$Some_Dir" -type f -name '*.gz' -print0)

Now you can just loop on the files to do whatever you want, e.g. since you said I want to match the pattern starting with ZRT and ending with _somenumber:

re='ZRT.*_somenumber'
for file in "${files[@]}"; do
    if [[ $file =~ $re ]]; then
        do whatever you like
    fi
done

Obviously you don't NEED the array of files in the first place, you could just loop directly on the output of find:

re='ZRT.*_somenumber'
while IFS= read -r -d '' file; do
    if [[ $file =~ $re ]]; then
        do whatever you like
    fi
done < <(find "$Some_Dir" -type f -name '*.gz' -print0)
1
  • When I pass ln -s $file after do. It is giving me the bug.
    – botloggy
    Commented Sep 15, 2021 at 15:21
1

It is possible to do this immediately in the process of finding files:

find Dir/ -name '*.gz' -regex '.*/ZRT[^/]*_[0-9]+/.*' -exec \
bash -c ': "$(grep -o "/ZRT[^/]*_[0-9]\+/" <<<"$0")";\
mkdir -p "${_#/}"; ln -s "$0" "${_#/}"' {} \;
1
  • I do not want to do it in the process of finding files as it is dependent on the previous outcome. Is there an alternative way?
    – botloggy
    Commented Sep 15, 2021 at 15:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .