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?

  • 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 '17 at 17:09
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.

  • 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 '17 at 17:06
  • @spencer.sm see my update. – Stephen Kitt Aug 8 '17 at 17:07
  • @spencer.sm You could add a little delay between two touch (via sleep) – user218374 Aug 8 '17 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 '17 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
  • 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 '17 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. – user4556274 Aug 8 '17 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 '17 at 17:12
  • 1
    Same problem as here: stackoverflow.com/q/3814290/3498950 – spencer.sm Aug 8 '17 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 '17 at 18:00

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.