Get index of argument with xargs?

2.6k views Asked by At

In bash, I have list of files all named the same (in different sub directories) and I want to order them by creation/modified time, something like this:

ls -1t /tmp/tmp-*/my-file.txt | xargs ...

I would like to rename those files with some sort of index or something so I can move them all into the same folder. My result would ideally be something like:

my-file0.txt
my-file1.txt
my-file2.txt

Something like that. How would I go about doing this?

2

There are 2 answers

9
anubhava On

You can just loop through these files and keep appending an incrementing counter to desired file name:

for f in /tmp/tmp-*/my-file.txt; do
   fname="${f##*/}"
   fname="${fname%.*}"$((i++)).txt

   mv "$f" "/dest/dir/$fname"
done

EDIT: In order to sort listed files my modification time as is the case with ls -1t you can use this script:

while IFS= read -d '' -r f; do
   f="${f#* }"
   fname="${f##*/}"
   fname="${fname%.*}"$((i++)).txt

   mv "$f" "/dest/dir/$fname"
done < <(find /tmp/tmp-* -name 'my-file.txt' -printf "%T@ %p\0" | sort -zk1nr)

This handles filenames with all special characters like white spaces, newlines, glob characters etc since we are ending each filename with NUL or \0 character in -printf option. Note that we are also using sort -z to handle NUL terminated data.

3
four43 On

So I found an answer to my own question, thoughts on this one?

ls -1t /tmp/tmp-*/my-file.txt  | awk 'BEGIN{ a=0 }{ printf "cp %s /tmp/all-the-files/my-file_%03d.txt\n", $0, a++ }' | bash;

I found this from another stack overflow question looking for something similar that my search didn't find at first. I was impressed with the awk line, thought that was pretty neat.