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

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
| improve this answer | |
  • This will only search the ROOTPATH directory, but not subdirectories... – Jaroslav Kucera Oct 12 '17 at 18:20
  • @JaroslavKucera: Yeah! OP didn't post that requirement though. The question just says on the path provided – Inian Oct 12 '17 at 18:21
  • I mean't subdirs. Btw, this returns nothing.. no errors – john jones Oct 12 '17 at 18:29
  • @johnjones: It worked fine for me! Which one did you try? The first or the second part? in the case of the latter, don't forget to enable the options included as shopt – Inian Oct 12 '17 at 18:31
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.

| improve this answer | |
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
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.