I'm trying to rename files (usually downloaded subtitle) using Autohotkey/RegEx to discard the unnecessary character, remove “.” to space in a way that the final renamed file will contain only name and the four digit year. An example as follows
Original file name/path
D:\Folder\Sub Folder\Hamburger.Hill.1987.BluRay.720p.x264.srt
Renamed file should be like this
D:\Folder\Sub Folder\Hamburger Hill 1987.srt
Initially I was intended only to remove the “.”. With contribution of “Ro Yo Mi” the AHK code is able to remove the “.” to space (Current Code Part 1) and it answered my initial question.
Later I realized there might possibility to also remove the unnecessary character (only to keep the name, year and also original file extension). Ro Yo Mi” also attempted with added new lines of code to rename the unnecessary string from the file name (Current Code Part 2). Although the code apparently showing capable to rename (show in the message code) but finally could not rename actually. There might some further upgrade or changes needed to make it operational to do the job as intended. Current status of the code could be found in the given reference.
Description
The problem the file wasn't getting renamed is because the path was not provided. Therefore AutoHotKey assumes that it's current working directory is where the changes will occur. Since the files aren't actually in the AutoHotKey's script directory, then the FileMove command fails.
This script assumes you'll be providing the fullpath and filename. So with this information this is how I'd remove the characters and rename the file using AutoHotKey.
#.:: ; Replace all "." (except before extension) with spaces
OldCLip := ClipboardAll
Clipboard=
Send ^c
ClipWait, 1
; MsgBox % Clipboard ; for testing
if ( Clipboard ) {
; set the value
String := Clipboard
; String := "D:\Folder\Sub Folder\the.Hamburger.Hill.1987.BluRay.720p.x264.srt"
; split string into the desired components: path, filename upto and including year, and extension
RegexMatch(String, "^(.*\\)(.*?[0-9]{4}).*([.][^.]{3})", SubPart)
FullPath := SubPart1
Filename := RegexReplace(SubPart2, "\.", " ") ; replace dots in the file name with spaces to improve readablity
Filename := RegexReplace(Filename, "i)^the\s+", "") ; remove the `the` and trailing spaces from the beginning of the filename if it exists.
Extension := SubPart3
NewPathFilename := FullPath . Filename . Extension
strMessage := "Renaming '" . String . "' to '" . NewPathFilename . "'"
MsgBox, % strMessage
FileMove, % String, % NewPathFilename
} ; end if
Clipboard := OldClip
return
Sample Message Box
Renaming 'D:\Folder\Sub Folder\the.Hamburger.Hill.1987.BluRay.720p.x264.srt' to 'D:\Folder\Sub Folder\Hamburger Hill 1987.srt'
Related
I'm trying to write a script in Autohotkey that will take the currently highlighted word, copy it into the clipboard, and then replace accented characters with their non-accented versions. For example, if the word honorábilem is in the clipboard, I want to change it to honorabilem.
This is what I have tried:
F1::
SetTitleMatchMode RegEx
clipboard =
Send, ^c
wordToParse := %clipboard%
wordToParse = RegExReplace(wordToParse,"á","a") ; also tried this: StringReplace, clipboard, clipboard, á, a, All
MsgBox, % clipboard
But the contents of the clipboard don't change. The á never gets replaced with a. Appreciate any help.
The contents of the clipboard don't change (after the change from sending CTRL+C) becuase you're simply not changing the contents of the clipboard after that.
And another mistake you have is assigning values to variables wrong.
I'd assume you don't know the difference between = and :=.
The difference is that using = to assign values is deprecated legacy AHK and should never be used. You're assigning literal text to a variable. As opposed to assigning the result of evaluating some expression, which is what := does.
This line wordToParse = RegExReplace(wordToParse,"á","a") assigns literal text to that variable instead of calling the RegExReplace() function and assigning its result to the variable.
Also, no reason to regex replace if you're not using regex.
The StrReplace() function is what you want.
And then there's also the usage of legacy syntax in an expression:
wordToParse := %clipboard%
Referring to a variable by wrapping it in % is what you'd do in a legacy syntax.
But since you're not doing that, you're using :=, as you should, just ditch the %s.
Revised script:
F1::
;This does nothing for us, removed
;SetTitleMatchMode RegEx
;Empty clipboard
Clipboard := ""
;Switched to SendInput, it's documented as faster and more reliable
SendInput, ^c
;Wait for the clipboard to contain something
ClipWait
wordToParse := Clipboard
wordToParse := StrReplace(wordToParse, "á", "a")
;Since you want to display the contents of the clipboard in
;a message box, first we need to set what we want into it
Clipboard := wordToParse
MsgBox, % Clipboard
return
I have a very long piece of code that I need to add to, and would prefer to do it using a script rather than write myself for fear of introducing errors.
I have commands that look like this
rename oldname newname
rename oldname2 newname2
I want to, whenever I see the command "rename" I want to add a "note" command
rename oldname newname
note newname: "A Note"
rename oldname2 newname2
note newname2: "A Note"
I am using Julia's read and write features to do this, and it has been very easy so far.
f = open("renaming.txt") # open input file
g = open("renaming_output.txt", "w") # open output file
for ln in eachline(f)
write(g, "$ln \n") # write the command, no matter what it is
stripped = lstrip("$ln") # Strip whitespace so I can use "startswith" command
if startswith(stripped, "ren")
words = split("$ln", " ") # split on space to get the "newvar" name
println("$ln \n") #check that I am working with a rename command
println("note ", words[3]":") # check that the note function prints
note_command = string("note ", words[3], ": \n") # construct the note command
write(g, note_command) #write it to the output file.
end
end
My issue is with the indentation. The above code writes the "note" command on the far left, without any indentation. However, Ideally I would like the note command to be indented one level further than the rename command. But I can't figure out how to capture all the preceeding whitespace.
I presume that the answer involves using the match and m.match functions, but I can't get it to work.
Any help would be appreciated.
On Julia 0.7 the simplest change in your code would be to replace
println("note ", words[3]":")
with
println(first(ls, search(ls, 'r')-1), " note ", words[3]":")
Using regular expressions you can write rx = r"(?:(?!r).)*" at the start of your code and then:
println(match(rx, ls).match, " note ", words[3]":")
In both cases we take care to retain the start of ls till 'r' in its original form.
With Julia 6.1, my solution, with the help the answer, is as follows
if startswith(stripped, "ren") & !startswith(stripped, "renvars")
leftpad = " " ^ search("$ln", 'r')
words = split(stripped, " ")
varname = string(leftpad, " note ", words[3], ": ", words[2], " \n")
print(varname)
write(g, varname)
end
With the leftpad = ^ search("$ln", 'r') being the key addition. Given that the left padding of my code is always tabs, I just insert the number of tabs as there are characters before the first r. This solution works in 0.6.1, but search may behave differently in .7.
I am trying to check if a string is in a string using RegEx in a AutoHotKey script.
If my string is a file path like this:
G:\htdocs\projects\webdevapp\app\folder\file.php
Then I need to extract the webdevapp part.
From the AutoHotKey docs it gives this example for a RegEx command that will store the found value to a variable:
; Returns 1 and stores "XYZ" in SubPat1.
FoundPos := RegExMatch("abcXYZ123", "abc(.*)123", SubPat)
So in theory something similar to this below except the regex part would need to be changed...
FoundPos := RegExMatch("G:\htdocs\projects\webdevapp\app\folder\file.php", "G:\htdocs\projects\(.*)\app\folder\file.php", DomainNameVar)
Any help in extracting that domain name from the file path into a variable in AutoHotKey?
It basically need to check if the string starts with G:\htdocs\projects\ and if it does then grab any character after that point until it comes up to the next \
I got it!
FoundPos := RegExMatch("G:\htdocs\projects\webdevapp\app\folder\file.php", "G:\\htdocs\\projects\\([^\\]+)*", DomainNameVar)
G:\\htdocs\\projects\\([^\\]+)*
Demo https://regex101.com/r/rFQRbT/1
I've been trying to figure something out for a while now and I can't seem to understand. I've looked everywhere and I still can't find it.
I'm trying to make a dictionary for an auto corrector with AutoHotKey and I need to replace the beginning of each line with "::" and somewhere in between the line with another "::"
like so:
::togehter::together
Now I have around 20,000 of these to add with no "::" yet and what I'm doing is this in the replace textbox:
Replace: ^
With: ::
Now it works fine for the first line BUT if I press replace all cause no way am I going to click 20,000 times on replace, it replaces not only from where I am to the bottom but also the beginning too. So every line now has a new "::" added.
So what I need is to be able to tell the replace at what line to stop instead of doing every single line.
Also if you could help me add the "::(word)" after the first ::(misspelled word) that would be a great help.
Image for reference
I have found that the regular expression replace-all of ^ with some text, i.e. to add some text at the start of every line, does not work in some versions of Notepad++. My workaround for this was to use the ^(.) as the search string and include \1 in the replacement. For your case the replacement would be ::\1. The effect here is to replace the first character of each line with :: plus the first character. In a quick test with Notepad++ v7.1, replacing ^ with :: worked as I would want.
Two things should be checked in the Replace dialogue before doing the replace-all: (1) that "Regular expression" is selected and (2) "In selection" is not selected.
The question is not clear how the two words in the input are separated, so assuming that one or more spaces or tabs is used the search string to use is ^(\w+)\h+ and the replace string is ::\1::.
This AutoHotkey script might do what you require.
It leaves unchanged lines that start with '::',
and prepends/replaces text in the others. You copy the original text to the clipboard, run this script, and then the desired text is put on the clipboard. (To create and run the script: copy and paste it into a text editor and save it as myscriptname.ahk, or myscriptname.txt and then drag and drop the file into the AutoHotkey exe file. Or alternatively, if you save it as an ahk file, and install AutoHotkey, you can double-click to run.) AutoHotkey
vText := Clipboard
vOutput := ""
VarSetCapacity(vOutput, StrLen(vText)*2*2)
StringReplace, vText, vText, `r`n, `n, All
Loop, Parse, vText, `n
{
vTemp := A_LoopField
if (vTemp = "")
if (1, vOutput .= "`r`n")
continue
if (SubStr(vTemp, 1, 2) = "::")
if (1, vOutput .= vTemp "`r`n")
continue
StringReplace, vTemp, vTemp, %A_Space%, ::, All
vOutput .= "::" vTemp "`r`n"
}
Clipboard := vOutput
MsgBox done
Return
I want to use AutoHotkey to implement sed like replacement on the clipboard. I have tried several different ways to implement it, although I would like to make something which can be easily extended and be as functional as sed. Ideally it would take the act and take the same commands as sed and replace the current clipboard with the output. Since I use Ditto I will then have both the origlinal and output saved.
The solutions I have thought of and tested are to either make a hotstring which performs one specific sed replacement, e.g. using RegExreplace:
; Make text in clipboard "Camel Case" (retaining all spaces):
:*:xcamelsc::
haystack := Clipboard
needle := "\h*([a-zA-Zåäö])([a-zåäö]*)\h*" ; this retains new lines
replacement := "$U1$2 "
result := RegExReplace(haystack, needle, replacement)
Clipboard =
Clipboard := result
ClipWait
sleep 100
send ^v
return
Another example is
;replace multiple underscore with one space
:*:xr_sc::
haystack := Clipboard
needle := "[\h]*[\_]+"
replacement := " "
result := RegExReplace(haystack, needle, replacement)
Clipboard =
Clipboard := result
ClipWait
return
The flaw with this system is that I would have to make ~500 combinations of hotstrings for each possible combination I would like to have (e.g. a separate hotstring which to make all space underscore). I am not sure how to easily extend this.
Another way to do this is to use a GUI which previews the output and makes it possible to do more things, as implemented in clipboard replace. For this to be satisfactory I have made a hotstring which opens the GUI with the initial replacement filled in, and a hotkeys which automatically performs the replacement and pastes the output, etc. This system only requires that I specify the thing to replace, but I would rather have a system similar to the above which uses variables for all possible replacements so that I can refer to e.g. /^[\t]// to directly perform replacement.
A solution to do this would be to have a hotstring activate if I type
"xr[a string of text to indicate what to replace][a string of text to indicate what to replace with]xx"
i.e. "xx" would take the word just typed, parse it into the command, and perform it.
This would mean that if I type "xr_sxx", the "s" part would be interpreted as two separate variables, and the "" would be assigned the needle and the "s" would be looked up in a table and then inserted in the replacement variable of the RegExReplace.
Does anyone know of a way to do this?
This system only requires that I specify the thing to replace, but I
would rather have a system similar to the above which uses variables
for all possible replacements so that I can refer to e.g. /^[\t]// to
directly perform replacement.
Does anyone know of an easy way to do this?
Rather than specifying Hotstring for each scenario to perform a similar function I've used a method with a Hotkey, Input, and values stored in an Associative Array's.
Here's an Example:
data := {"xcamelsc": ["\h*([a-zA-Zåäö])([a-zåäö]*)\h*", "$U1$2 "]
, "xr_sc": ["[\h]*[\_]+", " "]}
f1::
word := ""
key := ""
Loop {
input, key, V L1 M T1, {Space}{Enter}{Tab}
if (errorlevel == "EndKey:Space") {
if (data.HasKey(word)) {
sendInput % "{BackSpace " StrLen(word)+1 "}"
haystack := Clipboard
needle := data[word].1
replacement := data[word].2
result := RegExReplace(haystack, needle, replacement)
Clipboard =
Clipboard := result
ClipWait
sleep 100
send ^v
}
word := ""
Break
}
else {
word .= Format("{1:L}", key)
}
}
return
; Necessary for typing mistakes when using Input
$BackSpace::
word := SubStr(word, 1, -1)
sendInput, {BackSpace}
return
esc::exitapp