Insert characters at end of filename (before extension)? - ruby

I have image files that I want to append a string to the name of the file, right before the extension.
Example: example.png would turn in to example-2x.png
So, I want to insert -2x right before the extension, would could be just about any image type (png, jpg, gif, etc).
If there's an easy way to do this with Ruby, great.

Rake has a nice string extension for manipulating paths:
require 'rake/pathmap'
"images/example.png".pathmap "%X-2x%x"
#=> "images/example-2x.png"
From pathmap's docs:
%X -- Everything but the file extension.
%x -- The file extension of the path. An empty string if there is no extension.

This seems to work
img[/(\.\w+)/] = "-2x#{$1}"
img1 = 'foo.png'
img1[/(\.\w+)/] = "-2x#{$1}"
img1 #=> "foo-2x.png"
img2 = 'foo.bar.jpg'
img2[/(\.\w+)/] = "-2x#{$1}"
img2 #=> "foo-2x.png.jpg"

Use basename and extname to extract the two parts you want:
http://www.ruby-doc.org/core-2.0/File.html#method-c-basename
http://www.ruby-doc.org/core-2.0/File.html#method-c-extname

def insert_before_last_dot(str, part)
idx = str.rindex('.')
return str if (idx.nil? || idx==0)
str.clone.tap { |x| x[idx] = part.to_s + '.' }
end
insert_before_last_dot('foo.jpg', '-2px') # => "foo-2px.jpg"
insert_before_last_dot('foo.bar.jpg', '-2px') # => "foo.bar-2px.jpg"
insert_before_last_dot('foo') # => "foo"

Here's what I ended up doing that seems to work pretty well across pretty much any file type.
image = 'example.png'
ext = File.extname(image)
image_2x = image.gsub(ext, "-2x"+ext)

I dont know ruby myself, but I would expect that there is some sort of string.lastIndexOf() like in java. So you basically just find the last dot, split the string around that, and then reconcatinate it with the -2x

If you're working in a Linux environment, the rename function should work.
rename {,\-2x,*}.png
In tcsh and bash shells this expands to rename .png \-2x.png *.png

> "example.png".gsub /\.[^\.]*$/, "-2x\\0"
=> "example-2x.png"

I am sure that all of the above answers are more proper than mine but i find it effective to use the replace function...
Dir | Rename-Item -NewName {$_.name -replace ".pdf"," - 2012.pdf"}
So you just take the file extension .png and replace it with -2x.png
this should work with any file extension as you are just replacing it with the same or even a different file extension and add whatever text you want before the file extension.

Related

Search for a specific file name in a specific folder in laravel

everyone. So, what I basically want to do is to search for all files that start with "dm" or end with ".tmp" in storage_path("app/public/session").
I already tried File::allFiles() and File::files() but what I get is all files that are into that session folder and I can't figure out how to do it. What I could find in here is questions on how to empty a folder but that's not what I am looking for. Thanks.
Try this code :
$files = File::allFiles(storage_path("app/public/session"));
$files = array_filter($files, function ($file) {
return (strpos($file->getFilename(), 'dm') === 0) || (substr($file->getFilename(), -4) === '.tmp');
});
Or you can use the glob function like this :
$files = array_merge(
glob(storage_path("app/public/session/dm*")),
glob(storage_path("app/public/session/*.tmp"))
);
In Laravel, you can use the File facade's glob() method to search for files that match a certain pattern. The glob() function searches for all the pathnames matching a specified pattern according to the rules used by the libc glob() function, which is similar to the rules used by common shells.
You can use the glob() method to search for files that start with "dm" or end with ".tmp" in the "app/public/session" directory like this:
use Illuminate\Support\Facades\File;
$storagePath = storage_path("app/public/session");
// Find files that start with "dm"
$files = File::glob("$storagePath/dm*");
// Find files that end with ".tmp"
$files = File::glob("$storagePath/*.tmp");
You can also use the ? and [] wildcard characters,
for example ? matches one any single character and [] matches one character out of the set of characters between the square brackets,
to search for files that match more specific patterns, like this:
// Find files that starts with "dm" and ends with ".tmp"
$files = File::glob("$storagePath/dm*.tmp");
Note that, File::glob() method return array of matched path, you can loop and see the files or use it according to your needs.

How to get the name of file without extension? [duplicate]

This question already has answers here:
How to get filename without extension from file path in Ruby
(10 answers)
Closed 8 years ago.
Lets say I have this string ="C:/EFI/Ulta/Filename.rb" and Im trying to split only "Filename" from it.
I tried string.split.last and it returns "Filename.rb", I tried dropping the ".rb" but drop method isnt working for me. is there any other methods I can use?
f = "C:/EFI/Ulta/Filename.rb"
File.basename(f,File.extname(f))
#=> "Filename"
How to get filename without extension from file path in Ruby
When you don't have any specific preferences about the file extension, you can use the below trick. It works with 100% confidence.
string ="C:/EFI/Ulta/Filename.rb"
File.basename(string, ".*") # => "Filename"
The only difference with djsmentya answers is, I didn't use File::extname method. At least as per OP's example, I don't see any need to use ::extname method.
path = 'C:/EFI/Ulta/Filename.rb'
def filename_from_path(path)
parts = path.split('/').last.split('.')
(parts.size > 1 ? parts[0..-2] : parts).join('.')
end
filename_from_path(path)
should do it.
Examples:
filename_from_path('C:/EFI/Ulta/Filename.rb')
# => "Filename"
filename_from_path('C:/EFI/Ulta/Filen.ame.rb')
# => "Filen.ame"
filename_from_path('C:/EFI/Ulta/Filenamerb')
# => "Filenamerb"
Although the correct way to do it is probably with File.basename as per other answers.
If you are dealing with files you can use basename
File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb"
File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby"
Otherwise if it's just a string:
'C:/EFI/Ulta/Filename.rb'.split('/').last.split('.').first
EDIT
If you want a generic solution working based on string manipulation only, you can use this approach:
path = 'C:\file\path\to\file.rb'
match = match = path.match(/^.*(\\|\/)(.+(\\|\/))*(.+)(\.(.+))*$/)
filename = match.values_at(match.size-2)
This will work with unix and windows path's and filename with a more than one dot.

Copy a list of files from one directory to another - How to put text file into array?

Longtime lurker, first time posting! I'm new to Ruby so I would love some help on this.
I have a large text file with a list of files separated by a break, so it looks like this:
ARO_9501.jpg
ARO_9506.jpg
IMG_1499.jpg
IMG_1511.jpg
How can I get this text file into an array so I can call .each on it and copy the files to another directory?
This is how I generally do:
fileNameArray = File.read("/path/to/file.txt").split("\n")
Or, if you just need to iterate over the file names and don't necessarily need an array containing the names (it looks like you don't), I usually use this:
File.read("/path/to/file.txt").each_line do |line|
# do operations using line
end
Docs:
IO::read (File extends IO)
String .split() and each_line()
You can go this way also using IO::readlines :
ar = File.open("/home/kirti/ruby/foo.txt","r") do |fil|
fil.readlines.map(&:strip)
end
p ar
# >> ["ARO_9501.jpg", "ARO_9506.jpg", "IMG_1499.jpg", "IMG_1511.jpg"]
As per the #steenslag comments:
ar = File.readlines("/home/kirti/ruby/foo.txt").map(&:chomp)
ar # => [ "ARO_9501.jpg", "ARO_9506.jpg", "IMG_1499.jpg", "IMG_1511.jpg"]

find a file in a nested directory structure

I am attempting to find a file by its name within a directory. I am not sure what the best approach to this problem is. The file could be nested in other directories within the root directory.
You can use Dir.glob, for example:
Dir.glob(File.join("**","*.rb"))
It will recursively look for "*.rb" files in your current directory.
You could use Dir.glob or Dir[]:
Dir['the_directory/**/the_filename']
The ** matches 0 or more directories recursively. It returns an array of filenames that match.
this should work for you:
require 'find'
file_name = /log\Z/
path = './'
found_files = Find.find(path).inject([]) do |files, entry|
File.file?(entry) && File.basename(entry) =~ file_name ?
files << entry : files
end
p found_files
#=> ["./Maildir/dovecot.index.log", "./pgadmin.log"]
change file_name and path to your needs.

Replace backslahes in the accented file path

I tried to replace the backslahes in file path I got from Excel file:
path = "X:\Clients\BUT_Monétique Commerçant\2Gestion\4_Suivi\Suivi_Projet"
as follows:
path.gsub!("\\","/")
or
path.gsub!("\\","\\\\")
and no one worked. Any idea how to solve that. As you see, the URL contains some accented letters.
Are you actually using the following to define path?
path = "X:\Clients\BUT_Monétique Commerçant\2Gestion\4_Suivi\Suivi_Projet"
That doesn't work, at least in Ruby 1.8.7. You need to either use single quotes, or double the backslashes to escape them.
However, once you do that, the following works for me:
irb(main):001:0> path = 'X:\Clients\BUT_Monétique Commerçant\2Gestion\4_Suivi\Suivi_Projet'
=> "X:\\Clients\\BUT_Mon\303\251tique Commer\303\247ant\\2Gestion\\4_Suivi\\Suivi_Projet"
irb(main):002:0> path.gsub!("\\","/")
=> "X:/Clients/BUT_Mon\303\251tique Commer\303\247ant/2Gestion/4_Suivi/Suivi_Projet"
If that isn't working for you, can you paste the actual code that you are running, and the results that you get?
This works for me:
path = 'X:\Clients\BUT_Monétique Commerçant\2Gestion\4_Suivi\Suivi_Projet'
path.gsub!("\\","/")
p path
#=> "X:/Clients/BUT_Monétique Commerçant/2Gestion/4_Suivi/Suivi_Projet"
Alternately, you could just split on the backslashes and let Ruby's File class determine the filesystem-appropriate separator:
path = 'X:\Clients\BUT_Monétique Commerçant\2Gestion\4_Suivi\Suivi_Projet'
old_path = path.split("\\")
new_path = File.join(old_path)
p new_path
#=> "X:/Clients/BUT_Monétique Commerçant/2Gestion/4_Suivi/Suivi_Projet"

Resources