Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop through the sorted list of file names in two directories

Please note, i have read entries like For loop for files in multiple folders - bash shell and they ask for a significantly different thing.

I want to loop through the file names in a sorted order that exist in either of two directories. Files can potentially have spaces in them.

Let's say i have:

1/
  a
  a c b
  b
  c
2/
  a
  d

I would want to loop through: 'a', 'a c b', 'b', 'c', 'd'.

I have tried to do the following:

for fname in $((ls -1 -f -A "${dir1}"; ls -1 -f -A "${dir2}")|sort --unique); do
  echo "testing ${fname}"
done

the result then is

testing .
testing ..
testing a
testing a
testing c
testing b
testing b
testing c
testing d

For whatever reason i am getting '.' and '..' entries, that i was trying to exclude with -A, and also the file 'a c b' gets broken down into three strings.

I have tried to resolve it by adding --zero to the sort command, that changed nothing; by quoting the whole $(ls...|sort) part, and has resulted into a single entry into the for loop that has received the entire string with multiple lines each of which contained filename.

like image 586
v010dya Avatar asked Oct 28 '25 18:10

v010dya


1 Answers

Do not consciously ever parse output of ls command(See Why you shouldn't parse the output of ls(1) ), it has lots of potential pitfalls. Use the find command with its -print0 option to null delimit the files so that file name with spaces/newline or any meta-charactetrs are handled and subsequently use GNU sort with the same null delimit character, to sort them alphabetically & remove duplicate files. If dir1 and dir2 are shell variables containing the names of the folders to look up, you can do

while IFS= read -r -d '' file; do
    printf '%s\n' "$file"
done< <(find "${dir1}" "${dir2}" -maxdepth 1 -type f -printf "%f\0" | sort -t / -u -z) 
like image 82
Inian Avatar answered Oct 30 '25 08:10

Inian