Move files by date into different directory using CLI
Solution 1
Do not use ls
. It's not recommended to use in such cases. Moreover using grep
to filter according to date is not a good idea. You filename might itself contain 2012
string, even though it was not modified in 2012.
Use find
command and pipe its output.
find . -newermt 20120101 -not -newermt 20130101 -print0 | xargs -0 cp -t /your/target/directory
Here,
-newermt 20120101 ==> File's modified date should be newer than 01 Jan 2012
-not ==> reverses the following condition. Hence file should be older than 01 Jan 2013
-print0 and -0 ==> Use this options so that the command doesn't fail when filenames contain spaces
Solution 2
If you have newer files on the old disk that you want to ignore I would go about it like this
- Create a temporary marker file with a modified-by date that separates files I want from those I don't
- Copy files older than the marker file to the new location
Here are sample commands for this, which assume you want to maintain any directory hierarchy from the old disk in the new (cpio
is a copy command, similar to tar
or pax
):
touch -t 201201010000 /tmp/marker # YYYYMMDDhhmm == Jan 1st, 2012
cd /path/to/old/disk
find . -type f \! -newer /tmp/marker -print0 | cpio -pmd0 /path/to/new/disk
Solution 3
I think maybe this issue is very the same as yours, you also can check this out: Create sub-directories and organize files by date
I write this new script based on that issue's first answer:
for x in *; do
d=$(date -r "$x" +%Y)
mkdir -p "/your/new/directory/$d"
mv -- "$x" "/your/new/directory/$d/"
done
write this script to a file named
copy.sh
in your old directory.replace the
/your/new/directory
with your new directory's pathmake this file executable with
chmod +x copy.sh
then execute this file by
./copy.sh
Solution 4
You probably should use a batch tool for batch operations. Doing so will usually entail reading/writing all records in a single stream rather than, for example, invoking a separate cp
process for each file copied.
There is already a cpio
answer written here, which, given only the options already provided you is likely what I would choose. However, the cpio
format has been improved upon and folded into the standardized pax
archive format since its heyday. The same is true of tar
.
A strictly POSIX-pax
will not likely provide any options for directly filtering archive members based on file modification times - though the standard does specify the %T
list-mode format-modifier. Still, the most commonly available pax
implementation that I know of - which is the BSD version maintained by mirabilos - does extend this into a directly accessible CLI-switch.
For example, to copy only all files in the tree rooted at ./
which were last modified before ccyymmddHHMM
to /target/dir
you could do:
pax -rwT,201301010000 ./ /target/dir
To avoid recursing into child directories you might do instead:
pax -rwdT,201301010000 ./* /target/dir
See the man
page for more.
Related videos on Youtube
Erich Horn
Updated on September 18, 2022Comments
-
Erich Horn over 1 year
I am looking into the Object.create to create a custom RegExp class. I want to use pure JS and not JQuery or other library. After spending time researching on MDN, here and other places, I find that my expectations and understand are still not quite adequate for my task.
So far I have this:
( function ( SEAC ) { var _NativeRegExp = RegExp, _NativeRegExpProto = _NativeRegExp.prototype; SEAC.RegExp = function ( ) { _NativeRegExp.apply( this, arguments ); }; SEAC.RegExp.prototype = Object.create( _NativeRegExpProto ); } )( self.SEAC || ( self.SEAC = {} ) );
If I use it in the following code:
var re = new SEAC.RegExp( "[aeiou]+", 'g' ); var match = 'The quickening'.match( re );
I get this response:
TypeError: Method RegExp.prototype.toString called on incompatible receiver [object Object]
I hope this the intention and question is clear enough.
Anyone can explain to me what I am doing wrong and/or suggest how to do this? Or maybe my approach is not the best way, suggest another. I have done this before without using Object.create, but I wish to see if this is a better way to deal with inheritance and class creation.
Why I want to do this is of course I want to customize the class and some of the native methods.
-
Felix Kling over 10 yearsAccording to the specification, you cannot apply methods of
RegExp.prototype
to objects that are not instances ofRegExp
: "a TypeError exception is thrown if thethis
value is not an object or an object for which the value of the[[Class]]
internal property is not"RegExp"
." es5.github.io/#x15.10.6 . So I guess it's not possible to inherit fromRegExp
. -
Erich Horn over 10 yearsHmmm.... that's to bad, I guess I will have to go back to an instance of a RegExp object inside of my custom RegExp and have each method applying that object method and then returning it, shame I have to wrap everything.
-
-
Erich Horn over 10 yearsThanks Nick. That is tremendously insane. I experimented with making an instance from native RegExp from the same arguments in the constructor and returning that in toString and that also doesn't work, it won't throw, but it basically makes the regexp empty. That basically means your suggestion can work but with the limitation that toString can not be used in any useful way. thanks for the reply!
-
Nick Sharp over 10 yearsYeah, apparently RegExp plays crazy different from some of the other native Classes... its weird that it would, when you can do things with Array, Function and Object that you can't with RegExp... I played around with the making of a wrapper object that just in the constructor stores an internal reference to a RegExp instance and then just proxied the RegExp methods through... that seemed like the way to go. Still kinda derpy but functionaly clean
-
G-Man Says 'Reinstate Monica' almost 9 yearsYou might want to add some exception handling, so the script doesn't move itself into a
2015
directory. -
Hagen von Eitzen almost 9 yearsWon't `-exec mv {} /your/target/directory \;' instead of '-print 0 | xargs -0 cp -t /your/target/directory' work just as good regarding problems with spaces in names? (Also, the OP wanted to move not copy)
-
shivams almost 9 years^^ Yes. Both achieve the same objective.
-
roaima almost 9 yearsI guess I really ought to learn
pax
, buttar
andcpio
still stand me well. +1 -
mikeserv almost 9 years@roaima - strictly speaking, while there is an actual
pax
archive format (which is an extension to the ustar format), the POSIX-spec'dpax
utility reads/writes cpio, pax, and ustar formats. Because all three archive types amount primarily just to different means of encoding the metadata for many files alongside said files' actual data into a single stream, it isn't really too much of a stretch. I once wroteshitar
- which was just a few lines of shell-script for - mostlydd
-tar
ing block devs on the fly based on the POSIX spec. -
roaima almost 9 yearsI like your linked script; strangely it would have been very useful a couple of months ago for exactly that same purpose. Oh well. I might even try to stop using
cpio -H ustar
...