avoid recursion into specifc folder using filemanip - haskell

I am exploring the filemanip library to search for markdown files in a path including subfolders
import System.FilePath.Find
find always (fileType ==? RegularFile &&? extension ==? ".md") "a/path/"
is there any way to specify a folder name or pattern into which it should not recurse

Looking at the documentation we can see that find takes as first argument a RecursionPredicate which in turn is just FindClause Bool.
Based on this we can see that we have to pass in a custom RecursionPredicate to find other than always.
One example is to ignore .git directories:
notGit :: FindClause Bool -- or via type alias also a RecursionPredicate
notGit = directory /=? ".git"
We then just use our new recursion predicate with find:
find notGit (fileType ==? RegularFile &&? extension ==? ".md") path
Note also the special combinators for predicates to e.g. compose a notSvn predicate with our notGit predicate via (||?) to get a predicate that enters neither directories.

Related

How to get get string between two wildcards?

In adf, i want to pass file type with wildcards as a parameter. It should pick up similiar type files from source folder and copy into corresponding folder(created based on file type) in the target.
For example
I am passing xyz00r37 as a parameter with wildcard char *.To copy the file to target folder xyz00r37,need to get the string between wildcard *.This is my requirement.
In future, filetype name and length may vary.To copy the files dynamically regardless of file type, need to extract the string between * symbol.
You can use Azure Data Factory expression language functions to get rid of the "*" wildcard.
Here's a sample code where I split the input parameter (input=xyz00r37*) and got rid of the wildcard.
#split(pipeline().parameters.input, '*')[0]
There are many ways this can achieved . You have not shared the exact file format so few guess .
wildcardxyz00r37wildcard - #replace(pipeline().parameters.filename,'*','')
wildcardxyz00r37wildcard - #split(pipeline().parameters.filename,'*')[1]
wildcardxyz00r37 - #split(pipeline().parameters.filename, '*')[1]
xyz00r37wildcard - #split(pipeline().parameters.filename, '*')[0] ( as called out before ) .
I think replace option takes care of all the scenarios .
HTH

How could i find path to file by his name?

Sooo guys I have to find path to the file by his name
I've found this func. findExecutable but it's not working
F.e:
fileName <- getLine ("file.txt")
filePath <- findExecutable fileName
case filePath of
Nothing -> error "I can't find this file "
Just path -> print path
Even when I input "/home/.../file.txt" It's not working
How can I fix it
The type of func is findExecutable :: String -> IO (Maybe FilePath)
I give to this func "String" I'm check the result with const. case of but all time i'm getting error
This would happen if file.txt is not, in fact, executable.
The documentation for findExecutable specifically states (bold emphasis mine):
On non-Windows platforms, the behavior is equivalent to findFileWith using the search directories from the PATH environment variable and testing each file for executable permissions.
Try giving it the executable permission:
chmod +x /home/.../file.txt
Then try findExecutable again. Should work.
If you're trying to find the file regardless of it being executable or not, take a look at findFile instead.
Keep in mind, however, that, while for executables there is a rough definition of "find" (meaning "find anywhere on PATH"), this concept is generally not defined for regular files. This means that if you want to "find" a file, you have to specify precisely where you'd like to find it. This is what findFile's first parameter is for.

Finding all the files under a directory in turtle that match a pattern

I'd like to use the find function from the turtle package such that it matches any file path (in order to get an equivalent behavior to find . in bash). However I cannot find a wildcard pattern that I can use with this function.
find :: Pattern a -> FilePath -> Shell FilePath
I guess I could construct a pattern that matches any character zero or more times, but I'd like to avoid re-inventing the wheel.
lsif sounds more like what you want. The documentation contains an example how to print the complete tree:
lstree = lsif (\_ -> return True)
So in your case, you would use
lstree "."
Note that the output between find and lstree "." differs slightly: the original path isn't duplicated in the latter.

Scons. Go recursive with Glob

I using scons for a few days and confused a bit. Why there is no built-in tools for building sources recursively starting from given root? Let me explain:
I have such source disposition:
src
Core
folder1
folder2
subfolder2_1
Std
folder1
..and so on. This tree could be rather deeper.
Now I build this with such construction:
sources = Glob('./builds/Std/*/*.cpp')
sources = sources + Glob('./builds/Std/*.cpp')
sources = sources + Glob('./builds/Std/*/*/*.cpp')
sources = sources + Glob('./builds/Std/*/*/*/*.cpp')
and this looks not so perfect as at can be. Of cause, I can write some python code, but
is there more suitable ways of doing this?
As Torsten already said, there is no "internal" recursive Glob() in SCons. You need to write something yourself. My solution is:
import fnmatch
import os
matches = []
for root, dirnames, filenames in os.walk('src'):
for filename in fnmatch.filter(filenames, '*.c'):
matches.append(Glob(os.path.join(root, filename)[len(root)+1:]))
I want to stress that you need Glob() here (not glob.glob() from python) especially when you use VariantDir(). Also when you use VariantDir() don't forget to convert absolute paths to relative (in the example I achieve this using [len(root)+1:]).
Sure.
You need to write python wrappers to walking through dirs. You can find many recipes on stackoverflow.
Here is my simple function which returns list of subdirs in present dir (and ignore hide dirs starting with '.' - dot)
def getSubdirs(abs_path_dir) :
lst = [ name for name in os.listdir(abs_path_dir) if os.path.isdir(os.path.join(abs_path_dir, name)) and name[0] != '.' ]
lst.sort()
return lst
For example, i've dir modules what containts foo, bar, ice.
corePath = 'abs/path/to/modules'
modules = getSubdirs(corePath)
# modules = [bar, foo, ice]
for module in modules :
sources += Glob(os.path.join(corePath, module, '*.cpp'))
You can improve getSubdirs function adding recurse and walking deeper to subdirs.
The Glob() SCons function doesnt have the ability to go recursive.
It would be much more efficient if you change your Python code to use the list.extend() function, like this:
sources = Glob('./builds/Std/*/*.cpp')
sources.extend(Glob('./builds/Std/*.cpp'))
sources.extend(Glob('./builds/Std/*/*/*.cpp'))
sources.extend(Glob('./builds/Std/*/*/*/*.cpp'))
Instead of trying to go recursive like you are, its quite common to have a SConscript script in each subdirectory and in the root SConstruct call each of them with the SConscript() function. This is called a SCons hierarchical build.
Here is my version of recursive Glob:
from SCons.Environment import Base as BaseEnvironment
def __RGlob(self, root_path, pattern, ondisk=True, source=False, strings=False, exclude=None):
result_nodes = []
paths = [root_path]
while paths:
path = paths.pop()
all_nodes = self.Glob(f'{path}/*', ondisk=ondisk, source=source, exclude=exclude)
paths.extend(entry for entry in all_nodes if entry.isdir() or (entry.srcnode() and entry.srcnode().isdir())) # `srcnode()` must be used because `isdir()` doesn't work for entries in variant dirs which haven't been copied yet.
result_nodes.extend(self.Glob(f'{path}/{pattern}', ondisk=ondisk, source=source, strings=strings, exclude=exclude))
return sorted(result_nodes)
BaseEnvironment.RGlob = __RGlob
It tries imitate the standard Glob as closely as possible. The biggest difference is that beside the pattern is takes a root path as another argument. The pattern is then applied to this root path and every sub-directory in it.
This code adds function RGlob it to the base environment, which means you will be able to call it on every environment that is created after that. The best place to paste this is probably the file site_scons/site_init.py.
I use this:
srcdir = './'
sources = [s for s in glob2.glob(srcdir + '**/*.cpp') if "/." not in s]

Directory.GetFiles does not work as expected

string[] list = Directory.GetFiles("c:\\", "One Two Three - User.xml")
This code does not returns me array, but I have three directories with this file. Any ideas how to make it work?
Check out the variation of this method that takes a SearchOption, here. It seems that you're after a recursive direction search, and the SearchOption enumeration allows you to specify this.
Directory.GetFiles does not traverse subdirs in this way... so only file on C:\ is returned!!
If you need to search this pattern in a dir and in its subdirs you have to scan (recursively) all subdirs and then current dir. In every step you add files to a global variable (string[] files).
I think this example can be useful...
Or you can use Directory.GetFiles(path, pattern, SearchOption.AllDirectories);

Resources