0

I have code that traverses a directory, and finds all the files with a .xz extension

The problem is I cannot seem to figure out how to access each iterated file with .xz instead i get the value of ROOTPATH . what am i doing wrong?

ROOTPATH='/home/user/path'
for file in "$ROOTPATH"; do
find $PWD -name '*.xz'
echo "file is $file"
done

This outputs the files like:

/home/user/path/file1.tar.xz
/home/user/path/file2.tar.xz

then the echo portion prints:

file is /home/user/path

how can i access each of the iterated items, e.g.

/home/user/path/file1.tar.xz
/home/user/path/file2.tar.xz

thank you

3 Answers3

1

You are not using the glob *.xz to match the files in the path, when you do this, you don't even need the find command. Just do

ROOTPATH="/home/user/path"
for file in "$ROOTPATH"/*.xz; do
    [ -f "$file" ] || continue
    printf "%s\n" "$file"
done

The *.xz is a standard glob pattern to match all files with .xz extension in the path specified. The [ -f "$file" ] || continue is just a sanity check needed for gracefully handling the loop exit when the glob returns an empty result i.e. when no files are found.

If in by chance you are looking for files under the sub-directories also, enable the extended shell globbing option globstar to enable recursive match on the filenames and do

shopt -s globstar nullglob
for file in "$ROOTPATH"/**/*.xz; do
    printf "%s\n" "$file"
done
Inian
  • 12,807
1

You should not iterate over the result of find, see Why is looping over find's output bad practice?

Instead, call your script from within find:

find "$ROOTPATH" -type f -name '*.xz' \
    -exec sh -c 'for n; do printf "Got name %s\n" "$n"; done' sh {} +

or, to call a separate script:

find "$ROOTPATH" -type f -name '*.xz' \
    -exec /some/path/script.sh {} +

The script could look like:

#!/bin/sh

for name; do
    # do something with "$name"
done

The script, whether embedded with sh -c (or bash -c if you need bash) or separate, will in this case be called with as many .xz files as possible (it may be called several times if the number of files are in the hundreds). The for name loop will iterate over the found names and you can use $name (properly quoted, of course) to do whatever it is you need to do to the individual files.

Kusalananda
  • 333,661
0

Use find in the for cycle itself:

ROOTPATH="/home/user/path"
for file in `find $ROOTPATH -type f -name *.xz -print`
do
        echo "file is $file"
done