More efficient for loop on files

is there a more efficient way to write the following code:

                        for eachlfile in $(ls -ltcrd ${BACKUPDIR}/${BACKUPNAME}*/content_${BACKUPNAME}* 2>/dev/null | awk '{print $NF}')
                        do
                                echo "=========================="
                                echo ${eachlfile} | awk -F"__" '{print $NF}'
                                echo "=========================="
                                cat ${eachlfile}
                        done

i want to be able to run this on AIX, SunOS and LInux systems. So the solution should be portable.

Yes. Drop the -l, -t, -c, and -r options for ls , and you can also drop the awk pipe...

1 Like

Hello SkySmart,

Could you please let us know what you are trying to do here. Because I don't think you are trying to traverse directories and trying to get files, if you could explain your requirement with details, we could try to help.

Thanks,
R. Singh

1 Like

You can keep the ls -trcd options, but -l has to go. And parameter expansion in the shell is MUCH faster than invoking another awk per file processed. Maybe something more like:

			ls -tcrd | while IFS= read -r eachlfile 
			do
				echo "=========================="
				printf '%s\n' "${eachlfile##*__}"
				echo "=========================="
				cat "$eachlfile"
			done

would do what you want. This should work with ksh or bash on any of those systems. On a Solaris 10 or earlier SunOS system, you'd have to use /usr/xpg4/bin/sh instead of /bin/sh (if you insist on using a shell named sh ). The printf is safer than echo . The output from echo can vary depending on what characters are in the pathnames being printed; the printf will give you the pathname itself. Of course, with no indication of what the pathnames you're processing really look like, bite above is completely untested.

1 Like

I made a mistake in my last post... The first line:

			ls -tcrd | while IFS= read -r eachlfile

should have been:

			ls -tcrd ${BACKUPDIR}/${BACKUPNAME}*/content_${BACKUPNAME}* |
			while IFS= read -r eachlfile

I should have also noted that you can't cat a directory and with or without ls -d you can end up with directory names from your ls if there are any directories matching the pattern ${BACKUPDIR}/${BACKUPNAME}*/content_${BACKUPNAME}* . If that is a problem, you might want to consider changing the line:

				cat "$eachlfile"

to:

				if [ -f "$eachlfile" ]
				then	cat "$eachlfile"
				else	printf '*** Not a regular file. ***\n'
				fi