It's never a good idea to use the output of ls for anything except viewing in a terminal. See Why not parse ls (and what to do instead)?. Instead, use find:
find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
sort -z -k1,1 -r -n |
cut -z -f2 |
head -z -n 10 |
xargs -0r echo mv -t /home/balaji/regular_archive/
This requires the GNU versions of find, sort, cut, tail, and xargs (or, at least other versions of them that support the -z option for NUL record separators).
find uses -printf '%C@\t%p\0' to list the last-changed timestamps (%C@, in seconds since the epoch 1970-01-01 00:00:00) and filenames (%p) of all regular files. The fields are separated by a single tab (\t), and each record is separated by a NUL character (\0)
- the output of find is piped into sort to reverse sort (
-r) the files numerically (-n) on the first field only (-k 1,1) -- i.e. by the timestamp.
- sort's output is piped into cut to delete the timestamp field (we no longer need it after we've finished sorting)
- cut's output is piped into
head to get the first ten entries
- and finally, head's output is piped into
xargs to run the mv command. This uses the GNU -t extension to mv, so that the target directory can be specified before the filenames.
Actually, this runs echo mv rather than mv, so it's a dry-run. Get rid of the echo when you're sure it's going to do what you want.
Note: This will work with any filenames, no matter what weird and annoying characters they might have in them (e.g. spaces, newlines, shell metacharacters, etc). Also, The file command has many other options which can be used to refine the search criteria.
If you have an old version of GNU coreutils (i.e. < version 8.25), neither cut nor head nor tail will have -z options. You can use awk instead. e.g.
find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
sort -z -k1,1 -r -n |
awk -F '\t' 'BEGIN {RS=ORS="\0"}; NR<=10 { $1=""; $0=$0; $1=$1 ; print }' |
xargs -0r echo mv -t /home/balaji/regular_archive/
Alternatively, you could use perl instead of awk:
perl -F'\t' -0lane 'if ($. <= 10) {delete $F[0]; print @F}'
$iand/or$regular_archievein themvstatement, so... (2) check the values of$iand$regular_archieveto see if they're what you expect, and if not... (3) try to determine why and fix the problem; then, if you're still stuck... (4) edit your question to ask for help based on the additional information. – David Yockey Sep 27 '19 at 11:53echo $iandecho $regular_archiveinto thedoloop before themv? – David Yockey Sep 27 '19 at 11:53bash: work: command not founderror followed by several other errors (mostly due to simple syntax errors). You may want to consider testing your code in https://www.shellcheck.net/ Do this while you are writing it, not after finishing your script. Also test each command as you write them down in the script so that you know they do what you'd expect them to do. – Kusalananda Sep 27 '19 at 15:25