Bash Mac Terminal to Organize Filestructure - bash

I have 12,000+ files that need to be organized. All the folders are included, however the files are in a flattened filestructure right now.
My folders and files are all named with the path that they should be in. For example, in one directory I have a folder named \textures and another folder named \textures\actors\bear however there is no \textures\actors folder. I am struggling at developing a macro that will take these folders and put them in the correct place that each folder and filename suggests it should be in. I would like to be able to automatically sort these into textures and inside that would be actors and inside that would be bear. However, there are over 12,000 files so I am looking for an automated process that will determine all of this and just do it if possible.
Is there a script that will look at every file or folder name and detect which folder the file or folder should be in in the directory and automatically move them there as well as create any folders that do not exist within the path given when needed?
Thanks

Given a directory structure like this:
$ ls /tmp/stacktest
\textures
\textures\actors\bear
fur.png
\textures\actors\bear\fur2.png
The python script below will turn it into this:
$ ls /tmp/stackdest
textures/actors/bear
fur.png
fur2.png
Python script:
from os import walk
import os
# TODO - Change these to correct locations
dir_path = "/tmp/stacktest"
dest_path = "/tmp/stackdest"
for (dirpath, dirnames, filenames) in walk(dir_path):
# Called for all files, recu`enter code here`rsively
for f in filenames:
# Get the full path to the original file in the file system
file_path = os.path.join(dirpath, f)
# Get the relative path, starting at the root dir
relative_path = os.path.relpath(file_path, dir_path)
# Replace \ with / to make a real file system path
new_rel_path = relative_path.replace("\\", "/")
# Remove a starting "/" if it exists, as it messes with os.path.join
if new_rel_path[0] == "/":
new_rel_path = new_rel_path[1:]
# Prepend the dest path
final_path = os.path.join(dest_path, new_rel_path)
# Make the parent directory
parent_dir = os.path.dirname(final_path)
mkdir_cmd = "mkdir -p '" + parent_dir + "'"
print("Executing: ", mkdir_cmd)
os.system(mkdir_cmd)
# Copy the file to the final path
cp_cmd = "cp '" + file_path + "' '" + final_path + "'"
print("Executing: ", cp_cmd)
os.system(cp_cmd)
The script reads all the files and folders in dir_path and creates a new directory structure under dest_path. Make sure you don't put dest_path inside dir_path.

Related

Shell Script to create destination directory and paste the file

This is what I am trying to do. I have a json file in which I have set of files like test1.txt,
test2.txt,
new/destination/test3.txt,
test4.txt
But when the file is in directory format, I am getting error.
files=["test.txt",
"test2.txt",
"new/destination/test3.txt",
"test4.txt"
]```
Inside a Groovy script I have a sh:
In a for loop I am trying to copy those files to different directory,
`for( file in files) {
sh ("cp -pr source_directory/"+file + " destination_directory/"+file +"| true")
echo 'file to copy ' + file
}`
Result I am looking for :
** destination_directory/test1.txt
destination_directory/test2.txt
destination_directory/new/destination/test3.txt **
I know cp command wont create new directory, is there any way I can solve this?

Using Windows Command Line with Python Subprocess Module

So basically I've got the worst situation possible on Windows... A path with spaces on a drive other than C:/
I'm trying to run the following:
print(subprocess.check_call("cd d: && d: && " + '"' + dir_name + '"', shell=True))
Where dir_name is the name of the directory plus the name of the executable file. The way I get dir_name is as follows:
dir_path = os.path.dirname(os.path.realpath(__file__))
dir_name = (dir_path.replace("\\","/") + "/bowtie2-2.3.4-mingw-x86_64/bowtie2-build").replace(" ", "\\ ")
I've also tried a few different variants of dir_name:
dir_path + "/bowtie2-2.3.4-mingw-x86_64/bowtie2-build"
dir_path.replace("\\","/")+"/bowtie2-2.3.4-mingw-x86_64/bowtie2-build"
I've tried it with and without quotes surrounding the whole thing, I've tried it with and without the shell option, I've tried it in cmd.exe and basically every time I get something along the lines of:
The system cannot find the path specified.
The full path is essentially:
D:/My Documents/2018 Documents/Class Name/Assignment Name/Subfile/ProgramName
With the variants I've tried being:
D://My Documents//2018 Documents//Class Name//Assignment Name//Subfile//ProgramName
D:/My\ Documents/2018\ Documents/Class\ Name/Assignment\ Name/Subfile/ProgramName
D://My\ Documents//2018\ Documents//Class\ Name/Assignment\ Name//Subfile//ProgramName
"D:/My Documents/2018 Documents/Class Name/Assignment Name/Subfile/ProgramName"
"D:/My\ Documents/2018\ Documents/Class\ Name/Assignment\ Name/Subfile/ProgramName"
"D://My\ Documents//2018\ Documents//Class\ Name//Assignment\ Name//Subfile//ProgramName"
I'm up for anything at this point, thank you so much in advance!
EDIT #1:
Based on comments, I should add that I'm trying to run bowtie2-build which is an extensionless program in the Bowtie package. It takes two command-line arguments, an input file and an output file name.

FlashAir Execute on Write Event Properties

Using the dropbox sample code I am working on a Lua script that will run each time a new file is added (a photo in this case) to a specific folder. I see examples to iterate through a folders files to upload them each in turn. What I need is the properties that are passed to the file that will execute each time a new file is written. I'm hoping it will be passed the filename for the last file created so I can use that to upload the file directly to Dropbox or FTP site.
HI someone in japan solved your doubt as the following.
last_filepath = ""
max_mod = 0
fpath = "/DCIM/100__TSB"
for filename in lfs.dir(fpath) do
filepath = fpath .. "/" .. filename
mod = lfs.attributes( filepath, "modification" )
if mod > max_mod then
max_mod = mod
last_filepath = filepath
end
end
basically it set a directory to search for the latest file with newest modification date/time.
details r here
http://dotnsf.blog.jp/archives/1040120555.html

Create a directory and move files into it

I am taking screenshots using selenium for my cucumber test. I want one of my steps to place a screenshot file in a folder with a folder name generated using input from the step + time stamp.
Here is what I have accomplished so far:
Then /^screen shots are placed in the folder "(.*)"$/ do |folder_name|
time = Time.now.strftime("%Y%m%d%H%M%S")
source ="screen_shots"
destination = "screen_shots\_#{folder_name}_#{time}"
if !Dir.exists? destination
Dir.new destination
end
Dir.glob(File.join(source, '*')).each do |file|
if File.exists? (file)
File.move file, File.join(destination, File.basename(file))
end
end
end
If the directory does not exist, I want to create it. Then I want to place all screenshots into the new directory.
The folder is to be created in the same directory as the screenshots and then all screenshot files are to be moved into the folder. I am still learning ruby, and my attempts to put this together are not working out at all:
Desktop > cucumber_project_folder > screenshots_folder > shot1.png, shot2.png
In short, I want to create a new directory in screenshots and move shot1.png and shot2.png into it. How can I do so?
Based on the answer given this is the solution (for cucumber)
Then /^screen shots are placed in the folder "(.*)" contained in "(.*)"$/ do |folder_name, source_path|
date_time = Time.now.strftime('%m-%d-%Y %H:%M:%S')
source = Pathname.new(source_path)
destination = source + "#{folder_name}_#{date_time}"
destination.mkdir unless destination.exist?
files = source.children.find_all { |f| f.file? and f.fnmatch?('*.png') }
FileUtils.move(files, destination)
end
The source path is indicated in the step so different users do not have to modify the definition.
I'm not sure what's going on with your first line of code
Then /^screen shots are placed in the folder "(.*)"$/ do |folder_name|
as it's not Ruby code, but I've made it work with a notional line from a file.
The Pathname class allows things like destination.exist? instead of File.exist?(destination). It also lets you build composite paths with + and provides the children method.
The FileUtils module provides the move facility.
Note that Ruby allows forward slashes to be used in Windows paths, and it is usually easier to use them instead of having to escape backslashes everywhere.
I've also added a hyphen between the date and the time in the directory name, as otherwise it's pretty much unreadable.
require 'pathname'
require 'fileutils'
source = Pathname.new('C:/my/source')
line = 'screen shots are placed in the folder "screenshots"'
/^screen shots are placed in the folder "(.*)"$/.match(line) do |m|
folder_name = m[1]
date_time = Time.now.strftime('%Y%m%d-%H%M%S')
destination = source + "#{folder_name}_#{date_time}"
destination.mkdir unless destination.exist?
jpgs = source.children.find_all { |f| f.file? and f.fnmatch?('*.jpg') }
FileUtils.move(jpgs, destination)
end

Ruby: Copy contents of folder in zipfile

There is a zipfile. It can either have 10 files or one folder. This folder will have the 10 files. Now, if the zipfile has a folder, then i have to move all the files one directory above i.e.
zipfile.zip has folder. folder has 10 files. normally, if i unzip, i get zipfile/folder/10files. Now, I have to get like zipfile/10files. ie. move all the files one directory above.
How to do this? Please help.
If you don't mind using Linux unzip and really aren't worried about subdirectories:
def unzip(file)
to = File.join(File.dirname(file), File.basename(file, ".*"))
Dir.mkdir(to) unless File.exists?(to)
`unzip -j #{file} -d #{to}`
end
# unzip('yourfile.zip')
This method creates a new directory in the same directory as the zip file with the same name as the zipfile (minus extension). It then extracts (using unzip) the zip file into that directory, ignoring all paths (the -j flag tells unzip to junk paths).
EDIT
Per your comment, here is a way to do it without system calls:
def unzip(file)
Zip::ZipFile.open(file) do |zipfile|
to = File.join(File.dirname(file), File.basename(file, ".*"))
FileUtils.mkdir(to) unless File.exists? to
zipfile.each do |f|
if f.file? # Don't extract directories
fpath = File.join(to, File.basename(f.name))
zipfile.extract(f, fpath) unless File.exists?(fpath)
end
end
end
end

Resources