I have xml profiles stored in a folder that are switched dynamically. But the behavior is absolute path and I need a relative path. The lua code is written to work with both windows paths (back slashes) and with mac paths (forward slashes).
On my mac the path might be /folder/folder/profile1.xml. In normal application the program will return a file/location of profile1.xml. And it will find the next profile in the same folder.
If I direct the application to a new folder using a relative link such as ../profile2.xml then the program will find the new profile and returns the file/location as ../profile2.xml. Then it will not find the next profile within the same folder... it's either looking for the next profile out a step (../) or within the original folder as set by the application. I want it to find the next requested profile within this new folder location.
The existing code that sets the current profile and profile path is this:
local loadedprofile = '' --set by application
local profilepath = '' --set by application and modified below
The relevant switching functions seem to be:
local function setDirectory(value)
profilepath = value
end
local function setFile(value)
if loadedprofile ~= value then
doprofilechange(value)
end
end
local function setFullPath(value)
local path, profile = value:match("(.-)([^\\/]-%.?([^%.\\/]*))$")
profilepath = path
if profile ~= loadedprofile then
doprofilechange(profile)
end
I'm thinking I might need to modify the match criteria of the third function to remove the ../. Maybe something like this removing the optional .'s
local function setFullPath(value)
local path, profile = value:match("(.-)([^\\/]-([^%.\\/]*))$")
profilepath = path
if profile ~= loadedprofile then
doprofilechange(profile)
end
I really have no clue as to how to write this code, I'm just trying to tweak this open source code (MIDI2LR) to suit my needs. In my rudimentary understanding of the code it seems the match criteria is overly convoluted. But I would like to know if I am reading it right. I interpret it as:
:match("(.-)([^\\/]-%.?([^%.\\/]*))$")
(.-) --minimal return
( )$ --from the end of profile path
[^\\/]- --starts with \ or \\ or /, 0 or more occurrences first result
%.? --through, with dots optional
[^%.\\/]* --starts with . or \ or \\ or /, 0 or more occurrences all results
If I am reading it right it would seem the first "starts with" is entirely redundant, or that the "from the end" should be associated with the second "starts with."
I have commented out the setFullPath function without the desired results which makes me think that a match requirement might be needed added to the setDirectory function.
Any help is greatly appreciated as I am in way over my head. Thanks!
Your reading of the match is incorrect, here is a more accurate version:
:match("(.-)([^\\/]-%.?([^%.\\/]*))$")
(.-) -- Match and grab everything up until the first non slash character
( )$ -- Grab everything up until the end
[^\\/]- -- Starts with any character OTHER THAN \ or /, 0 or more occurrences first result
%.? -- single dot optional in the middle of the name (for dot in something.ext)
[^%.\\/]* -- Any character OTHER THAN . or \ or /, 0 or more occurrences
A few notes - %. is a literal dot. [^xyz] is the inverse class, so every character other than x, y, or z. \\ is actually just one backslash, this is due to the escaping in a string.
This simpler version would break it in a similar way that is easier to work with: value:match("(.-)([^\\/]+)$")
You may want to provide more information on the profile loading behavior, its hard to tell what you need the code to do. What value would path and profile have in the example you give?
Related
I want to pass into a variable, the language of the user.
But, my client can't/didn't pass this information trough datalayer. So, the unique solution I've is to use the URL Path.
Indeed - The structure is:
http://www.website.be/en/subcategory/subsubcategory
I want to extract "en" information
No idea to get this - I check on Stack, on google, some people talk about regex, other ones about CustomJS, but, no result on my specific setup.
Do you have an idea how to proceed on this point ?
Many thanks !!
Ludo
Make sure the built in {{Page Path}} variable is enabled. Create a custom Javascript variable.
function() {
var parts = {{Page Path}}.split("/");
return parts[1];
}
This splits the path by the path delimiter "/" and gives you an array with the parts. Since the page path has a leading slash (I think), the first part is empty, so you return the second one (since array indexing starts with 0 the second array element has the index 1).
This might need a bit of refinement (for pages that do not start with a language signifier, if any), but that's the basic idea.
Regex is an alternative (via the regex table variable), but the above solution is a little easier to implement.
I am trying to come up with a regex (PCRE) that finds current windows NTUSER.DAT files when cycling through a file list (valid NTUSER.DAT are the ones that are in the correct path for use by Windows).
I am trying to exclude any NTUSER.DAT files that have been copied by a user and placed in a different location (e.g. on the Desktop). In the following sample data, the first 4 results are valid, the next 3 are invalid:
\Users\John Thomas Hamilton\ntuser.dat
\Users\Default\NTUSER.DAT
\Users\Mary Thomas\NTUSER.DAT
\Users\UpdatusUser\NTUSER.DAT
\Users\John Thomas Hamilton\Desktop\My Stuff\Windows\Users\Default\NTUSER.DAT
\Users\John Thomas Hamilton\Desktop\My Stuff\Windows\Users\Student\NTUSER.DAT
\Users\John Thomas Hamilton\Desktop\My Stuff\My stuff to sort\Tech Support Fix it\NTUSER.DAT
Currently the best/simplest regex I have is:
\\USERS\\[A-Z0-9]+\\NTUSER.DAT$
but of course there a plenty of valid Windows file name characters other than letters and numbers that could exist in the user name.
I think i need to search up to the first occurrence of the new folder "\" and then if it does not have NTUSER.DAT after it, reject it. I have not had any luck doing this so any help would be appreciated.
Well assuming you have a valid file list, this would work:
^\\Users\\[^\\]+?\\NTUSER.DAT$
Make sure you ignore case.
The secret is using [^\\]+? instead of .+? so that you match exactly one folder length in.
I need a nice column for Centrify tool which include all the log files under the different folders, for example;
/oradata1/oracle/admin/A/scripts/rman_logs/*.log
/oracle/oracle/admin/B/scripts/rman_logs/*.log
/oradata2/admin/C/scripts/logs/*.log
I used this but after the * character user can see all logs;
/ora(data(1|2)|cle)/oracle|admin/admin/*/scripts/rman_logs
/ora(data(1|2)|cle)/oracle|admin/admin/*/scripts/rman_logs
Which expression I must use.
If I understandy our question correctly, you want only .log files. You can use a positive lookahead to assert that it is indeed a log file (contains .log at the end of filename), and match the filename whatever it is (.*).
Then it's really easy. (?=.*\.log(?:$|\s)).* Of course, you can also add specific folders if you wish to restrict the matches, but the positive lookahead will still do its work. I.e. (?=.*\.log(?:$|\s)).*/scripts/.*
EDIT: As your comment, you only need those folders, so you just specify their filepaths in alternations and add [^.\s\/]*\.log at the end. So:
(?:\/oradata1\/oracle\/admin\/A\/scripts\/rman_logs\/|\/oracle\/oracle\/admin\/B\/scripts\/rman_logs\/|\/oradata2\/admin\/C\/scripts\/logs\/)[^\s.\/]*\.log You may shorten the regex by trying to combine filepath elements, but, imo, not necessary as you might as well specify each filepath individually, if they don't overlap too much.
I have found a global expression.
this is not a good way but it works and save me from lots of job. The main files are under the ....../scripts/rman_logs/ for all servers so I use this way.
I can produce these lines and can be a command group for users so this works good
tail /////scripts/rman_logs/*.log
tail ////scripts/rman_logs/.log
Thanks for your helps.
I'm going through a coldfusion code and encountered following information. I didn't understand some part of it. My questions are as follows:
CODE:
<cfif FINDNOCASE( "xyz.seta", "#CGI.SERVER_NAME#") GT 0 >
<cfset PublicPath = "abcxyz/NEW_abc/Public">
<cfset SessionPath = "abcxyz/NEW_abc/Session">
I understand that FINDNOCASE is used to find the first occurance of a substring in a string, from a specified start position.
Function Syntax: FindNoCase(substring, string [, start ])
1) So, in my case, xyz.seta substring is searched starting from " #CGI.SERVER_NAME# " ? Am I confused here?
2) Question Regarding the PublicPath and SessionPath defined:
When I checked the server (after logging into it using VNC Viewer), only folders that are visible to me are Public and Session. Where can I find the path before it? Please clarify or let me know if I need to study something more before asking such question.
Thanks
You are correct about your first assumption. The FINDNOCASE will return the index of the start of the sub-string. I think that CF indexes are one based (not 0 based). Thus if the string "xyz.seta" exists in the variable #CGI.SERVERNAME#, the value returned will always be greater than zero and the contents of the CFIF block will execute.
On the variables PublicPath and SessionPath. These variables are page variables as they are not defined by any other scope designation (e.g. session or application). They only exist when this page is processing. If this is in your Application.cfm, it will execute every time this Application.cfm file is called. The values of the variables are being set to paths relative to the the current directory. If you want them absolute, add a slash to the front of the string literals (e.g. "/abcxyz/NEW_abc/Public"). That will make them absolute paths from the document directory of the web server. The web server path varies from OS to OS.
I have no idea what your second question is even asking, let alone the answer, but I can answer the first one.
You are misreading the (fairly clear, I thought) docs for findNoCase().
Function Syntax:
FindNoCase(substring, string [, start ])
Code:
FINDNOCASE( "xyz.seta", "#CGI.SERVER_NAME#")
So xyz.seta is the substring, and CGI.SERVER_NAME is the string. And the optional start attribute is not specified, so is implied to be 1, ie: the beginning of the string.
So the code is looking for xyz.seta within the value of CGI.SERVER_NAME (and will return the position at which it is found, or zero if not found.
This is a pretty simple configuration statement.
If the address that is being accessed (CGI.server_name) at least contains the domain xyx.seta then set these two variables, PublicPath and SessionPath, to be these two values.
I imagine that there is an else that says set the paths to be two different values.
If you look on the server where xyz.seta is hosted you should find those physical file paths.
That's it really. Nothing more nothing less.
You might want to use cfdump and cfabort to umm... dump out the content of CGI scope and variables scope to see what is in there and what is being set. Use cfabort to stop processing immediately after the cfdump.
That should help you to understand what variables are there available to you and what the code above is doing.
FindNoCase(substring, string [, start ])
is the syntax where the "start" is an optional parameter which is not passed here.
The substring "xyz.seta" is searched into the "CGI.SCRIPTNAME". The findnocase function returns 0 if no matches found or a positive number if found(The returned value is the starting index of the substring into the string and the index starts from 1 and not 0). So the statement can be as
<cfif FINDNOCASE( "xyz.seta", "#CGI.SERVER_NAME#")>
as the return value will be positive if matches are found
I'm trying to load multiple .txt files in R, from different folders.
I have problems writing the path and pattern using regular expressions.
My path has this structure:
'/Users/folderA/folderB/folderC/folderD/01_01_2012/folderE/file.txt'
So, the path is almost the same, except that the folder with the date name always changes.
I have tried to load it like this:
filesToProcess <- list.files(path = "/Users/folderA/folderB/folderC/folderD/",
pattern = "*_*_*/folderE/*.txt")
But this doesn't seem to work.
Could someone please help me writing down this with regular expressions?
Thanks a lot!
The key here is to use argument recursive=TRUE so that you can search inside the folders that are in the original directory:
filesToProcess <- list.files(path = "/Users/folderA/folderB/folderC/folderD",
pattern = "txt", recursive = TRUE, full.names = TRUE)
The pattern has to correspond to the name of the files, it can't refer to the name of the folders (see ?list.files). That's why you need a second step where you have to narrow down to the specific folders you wanted. Note the use of argument full.names=TRUEin the previous call that allow us to keep the path of each file (NB: you also have to drop the final / of the path argument or else it ends up doubled in our output and leads to an error when you'll try to upload the files).
filesToProcess[grep("folderE", filesToProcess)]
A final note:
Your regular expression was flawed anyway: * means
The preceding item will be matched zero or more times.
What you wanted was .: see ?regexp
The period . matches any single character.
Although the subject refers to regular expressions it seems from the example that you really want to use globs. In that case try:
Sys.glob("/Users/folderA/folderB/folderC/folderD/*_*_*/folderE/*.txt")