After a few set of tests, I think I finally found out the problem.
I will document what I've found and in the end you'll find the actual solution.
There's always the chance that there are other variables in your scenario, but I hope this will help in some way.
**
The problem
Currently there is a sort of a built-in security mechanism in which certain files and file content are being blocked, to prevent harmful code execution.
File types such as .aspx are blocked by the api, meaning you cannot create your own or upload your own files, even copying from other sites won't work while this mechanism is enabled.
Some examples:
SharePoint Designer, renaming .txt to .aspx

File Explorer, renaming .txt to .aspx

The same will happen if we do any file creation, copying or moving through the api (401 unauthorized).
**
The solution
There are 2 settings that prevent script files and script content:
You'll need to disable at least DenyAddAndCustomizePages, which will automatically stop blocking your .aspx files.
I happen to have a gist here, even though it's a one liner to set it up:
https://gist.github.com/tiagoduarte/4e5e40bd19c29ed7d16e5412445f09e3
With the blocking problem out of the way, you can chose your flavor:
- Use file explorer / manual reorganization
- Code it in a method of choice
Here's a working example:
Console.WriteLine("Copying pages...");
ClientContext context = GetContext(webUrl);
Web web = context.Web;
List sourceList = web.Lists.GetByTitle("Site Pages");
ListItem sourceItem = sourceList.GetItemById(3);
context.Load(sourceItem);
context.Load(sourceItem.File);
context.Load(web.Webs);
context.ExecuteQuery();
Web subWeb = web.Webs[0];
List destList = subWeb.Lists.GetByTitle("Site Pages");
context.Load(destList);
context.Load(destList.RootFolder);
context.ExecuteQuery();
string newFileUrl = destList.RootFolder.ServerRelativeUrl + "/" + sourceItem.File.Name;
Console.WriteLine("Copying " + sourceItem.File.ServerRelativeUrl + " to " + newFileUrl);
FileInformation fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, sourceItem.File.ServerRelativeUrl);
Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, newFileUrl, fileInfo.Stream, true);
context.ExecuteQuery();
**
Sources
Types of files that cannot be added to a list or library
Access denied when uploading page to SitePages library in SharePoint Online
Enable-SPDesigner.ps1
SharePoint Online Management Shell
TL;DR
Disable DenyAddAndCustomizePages property of the SPOSite object