0

I have a list of files that are space separated and I want to use the touch command to update their timestamps in that order. But when I supply the filenames as arguments, the timestamps get updated in a different order.

touch 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt 10.txt 11.txt 12.txt 

After running the command above and running ls -t (sorting by time modified) I get the following:

1.txt 10.txt 11.txt 12.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt

Does supplying arguments to commands not guarantee the execution order? If not, how can I update the timestamps of those files in that specific order?

1
  • 2
    If they all have the same timestamp, ls will show them in alphabetical order, which is what is happening. You probably need to introduce an artificial delay, e. g. for i in {1..12}; do touch ${i}.txt; sleep 1; done.
    – DopeGhoti
    Aug 8, 2017 at 17:09

2 Answers 2

5

With no time specified, touch changes the timestamps of all its arguments to the current time at the time each file is touched, which should produce a different timestamp for each file, but in many cases this ends up applying the same timestamp to all its arguments; you can verify this by running stat on all the touched files. They are processed in the order specified on the command line.

To get the result you want, you need to loop and touch each file individually, with some delay:

for file in {1..12}.txt; do touch $file; sleep 0.1; done

(with more or less delay depending on the timestamp resolution of the underlying file system).

Note that ls -t lists files sorted by descending timestamp; to see increasing times you need to use ls -rt.

4
  • It looks like even using a loop, it executes quickly enough to all have the same timestamp. Do you know of another alternative?
    – spencer.sm
    Aug 8, 2017 at 17:06
  • @spencer.sm see my update. Aug 8, 2017 at 17:07
  • @spencer.sm You could add a little delay between two touch (via sleep)
    – user218374
    Aug 8, 2017 at 17:07
  • It looks like on my system it can only be sorted to the nearest second. That's why it wasn't showing the correct order using ls. Even stat only went to the second. But after giving it a delay of 1 second it worked for my purposes.
    – spencer.sm
    Aug 8, 2017 at 17:22
0

Maybe it's a little cumbersome, but if it's in a script, I would use a for loop.

ex:

for x in 1.txt 2.txt 3.txt 4.txt [as many as you want here]; do touch $x; done

This would result in them always being created in the order given. You of course can change the names to be whatever and not follow any sort of pattern. If you are creating files with the same name or a numeric pattern like in your example, I would do this:

for x in $(seq 1 10); do touch $x.txt; done
5
  • That actually doesn't work. Try using ls -t after and you'll see that it goes in the same order I do not want... 1, 10, 11, 12, 2, 3...
    – spencer.sm
    Aug 8, 2017 at 17:03
  • 1
    @spencer.sm, provide the output of ls -l --full-time. I do not observe that ls's time sorting respects sub-second precision. However, using --full-time or getting the time via stat shows the files were indeed touched in the desired order. Aug 8, 2017 at 17:09
  • 1
    @spencer.sm It worked fine for me. ls -t as well as ls -l --full-time both showed them in the exact order 12.txt, 11.txt, 10.txt, 9.txt.... Your output seems to be showing numerical sorting.
    – Allan
    Aug 8, 2017 at 17:12
  • 1
    Same problem as here: stackoverflow.com/q/3814290/3498950
    – spencer.sm
    Aug 8, 2017 at 17:23
  • Well it probably depends on your system then. Stephen Kitt is absolutely right then, you need to add delay to the loop.
    – Allan
    Aug 8, 2017 at 18:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .