2

I have a bunch of folders which are labelled in this way:

 conf1
 conf2
 ...

But the order in the home directory is like

 conf1
 conf10
 conf100
 conf101
 ...
 conf2
 conf20
 conf200
 conf201
 ...

Because each folder contains a file named "distance.txt", I would like to be able to print the content of the distance.txt file, from each single folder, but in order, going from folder 1-->2-->3... to the final folder 272.

I tried several attempts, but every time the final file contains the all set of values in the wrong order; this is the piece of code I set:

   ls -v | for d in ./*/; 
     do (cd "$d" && cat distance.txt >> /path/to/folder/d.txt
         );
     done

As you can see I tried to "order" the folders with the command

ls -v

and then to couple the cycle to iteratively save each file.

Can you kindly help me?

  • for d in $(ls -vd conf*); do echo "$d"; done? – Cyrus Mar 12 '17 at 17:00
  • Hi! Thanks! I didn't know there was the possibility to "merge" the command ls in a for loop. Really useful! Thanks a lot! – Tommy Mar 12 '17 at 17:14
  • I would point out that this approach causes problems when filenames contain spaces, tabs or line breaks. In general, it is not recommended to parse the output of ls command. – Cyrus Mar 12 '17 at 17:21
5

For such a relatively small set of folders you could use a numerical loop

for n in {1..272}
do
    d="conf$n"
    test-d "$d" && cat "$d/distance.txt" >> /path/to/folder/d.txt
done
3

If you have a sort that supports null delimiters and version sorting, you could safely do

printf '%s\0' conf*/ | sort -zV | while read -rd '' d; do 
  whatever with "$d"
done

I think. If you have zsh it's much easier since it supports a numeric glob qualifier

for d in conf*(/n); do
  whatever with "$d"
done
  • Ok, thanks a lot Steeldriver, I will take into account your hints! Thanks a lot! – Tommy Mar 12 '17 at 17:13
0
printf '%s\n' conf{1..101} conf{2..272} |
xargs sh -c 'shift "$1"; printf "%s/distance.txt\n" "$@"' 2 1 > /path/to/folder.txt

Or,

printf '%s\n' conf{1..101}/distance.txt conf{2..272}/distance.txt |
xargs cat > /path/to/folder.txt
  • Ok, thanks a lot Rakesh, I will take into consideration your suggestion! Thanks again! – Tommy Mar 12 '17 at 17:13
0
printf 'conf%s/distance.txt\n' {1..272} | xargs cat >/path/to/folder/d.txt 2>/dev/null

Here we make use of the fact that if the dir. confNNN/ &/or distance.txt do not exist, a warning will be generated which we ignore. The real output happens only in case the dir+file exists, hence no need for testing file & dir. existence. cat to the rescue.

Also there is no appending >> required, as the xargs even if it invokes cat multiple times, it still dumps the output in one bunch into the log.

So it's one place which is not a UUOC ;-)

0

Create a tiny perlscript to sort the arguments passed by the shell:

#!/usr/bin/perl -l -s

$re ||= qr/(\d+)/;

sub bynum {
   ($aa) = $a =~ $re;
   ($bb) = $b =~ $re;
   return $aa <=> $bb;
}

map { print } sort bynum @ARGV;

Save the script as sortargsbynum and call it as shell expression:

for d in $(sortargsbynum conf*); do
   cat $d/distance.txt >> /path/to/folder/d.txt
done

You can pass a special regular expression for matching, for example to only match a number at end of the name:

for d in $(sortargsbynum -re='(\d+)$' *conf*); do
   echo $d
done

conf1
conf2
conf10
conf20
conf99
1stconf100
2ndconf100
conf101
conf200
conf201
0

You can sort first by length of string, then lexicographically if everything shares a common prefix. If two numbers share the same number of digits, then lexicographic and numerical comparison result in the same order.

 ls -1 | awk '{print $1 " " length($1)}' | sort -n -k2,2 -k1,1 | awk '{print $1}'

You can also use perl to collect the names of the folders and then extract the trailing numerical suffix. Then you can sort numerically based on this suffix.

ls -1 | perl -e '@lines = <STDIN>; @lines = sort { $a =~ /(\d+)$/; $aa = $1; $b =~ /(\d+)$/; $aa <=> $1;  } @lines; print foreach @lines;'

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.