File pattern to use for fetching files from FTP Server in Unix - unix

I've an issue with file name pattern to be provided in order to fetch the pattern file from the FTP server.
Currently, I am using ABC_YYYYMMDD*.sha1 as the pattern to fetch files. It fetches the last file using the above pattern. Sometimes, .gz.sha1 comes later and sometimes, the other one.
ABC_20160801060000.sha1
ABC_20160801060000.txt.gz.sha1
I would need to provide the file name pattern in such a way that the file should always pick ABC_YYYYMMDDHHMISS.sha1 only.
Need a fool proof pattern which matches the required one only?

You can use find -regex option for matching these file-names:-
find . -type f -regextype posix-extended -regex '.*ABC_20[0-9]{2}(0[1-9]|1[0-2])([0-2][0-9]|3[0-1])([0-2][0-3])([0-5][0-9])([0-5][0-9])\.sha1'
Am using the -regex flag supported by find for this over the -name flag which does simple glob pattern matching.
The man page of find says below for the -regex:-
-regex pattern
File name matches regular expression pattern. This is a match
on the whole path, not a search.
-regextype name
This option controls the variety of regular expression syntax
understood by the ‘-regex’ and ‘-iregex’ tests. This option is
positional; that is, it only affects regular expressions which
occur later in the command line. If this option is not given, GNU
Emacs regular expressions are assumed.
More about posix-extended regex type at this page. Other supported regex-types can be found here.
To see it in action:-
$ ls ABC_2016*
ABC_20161231225950.sha1 ABC_20169231225990.sha1
$ find . -type f -regextype posix-extended -regex '.*ABC_20[0-9]{2}(0[1-9]|1[0-2])([0-2][0-9]|3[0-1])([0-2][0-3])([0-5][0-9])([0-5][0-9])\.sha1'
./ABC_20161231225950.sha1
Update:-
If the regextype is not supported in the find version, a simple glob construct using the -name flag can be used to achieve the same.
$ ls ABC_2016*
ABC_20161231225950.sha1 ABC_20169231225990.sha1
$ find . -type f -name 'ABC_2[0-9][0-9][0-9][0-1][0-2][0-3][0-9][0-2][0-2][0-5][0-9][0-5][0-9].sha1'
./ABC_20161231225950.sha1

Related

Passing wildcards to find

I'm trying to automate my test runner better. For that I need the update file name in a variable. As this name depends on a the version I'm trying to use a find with a pattern to get the file name. That works just fine in bash.
However if I use that same pattern in expect find complains that it can't find anything.
My guess is that expect is doing something to my wildcards. However my experiments with {}, "", '' or \ didn't result in it working.
I guess I could create a helper sh script to write it into a file and then read that file but I don't like that solution and there has to be an option to pass characters with special tcl meaning as arguments.
At the moment my call looks something like this with an absolute path in front of the pattern:
set pattern {[0-9]*/*test*}
set updateFile [exec find ${pattern} -type f]
The result is that find reports '[0-9]*/*test*': No such file or directory. The pattern is what I would expect and when I call find [0-9]*/*test* -type f in bash it results in the expected file path. Find also works fine as long as I don't have any wild cards.
Has anybody an idea what is wrong?
When you run find [0-9]*/*test* -type f in Bash, it's Bash who interprets the wildcard [0-9]*/*test* and expand it to multiple files. And then Bash would pass the expanded multiple files to find. That's to say find never sees the wildcard.
For exec find $pattern -type f, Tcl would not interpret what's in $pattern and pass it directly to find. Unfortunately find also does not interpret the wildcards here so it fails with error like find : '[0-9]*/*test*': No such file or directory.
To work around, you can invoke find with bash -c:
exec bash -c "find $pattern -type f"

find command in unix withe regex

Can someone tell me what this command does : find ./ -regex ".*"\!*"*" ?
Guess based on too little information in the question:
This may be part of the definition of an alias like
alias f 'find ./ -regex ".*"\!*"*"'
for csh or tcsh which could be called like
f some pattern
to recursively find files that somehow match the specified pattern.

How to list the file created using command $touch " " having blankspaces only in the name of the file

I want to list the file which only have blankspaces in the name nothing else.
e.g file created using command touch " ".
This will create a file having 3 blank spaces.
I am using the following command but it's not listing the desired files.
ls -lart | grep '[^a-zA-Z0-9]'
Do not parse ls. Instead, you can use find with regular expressions:
find . -regextype posix-extended -regex '^.*/ *$'
Since man find says This is a match on the whole path, not a search, we can just say (credits to John Kugelman):
find . -regextype posix-extended -regex '.*/ *'
This will find files consisting in multiple spaces.
You can list it the same way you would any file: by name, or with a pattern that matches only it.
ls -lart " "
The pattern requires shopt -s extglob in bash (other shells may have something simliar). One possibility:
ls -lart "+([[:space:]])"

why is zsh globbing not working with find command?

I have been using zsh globbing for commands such as:
vim **/filename
vim *.html.erb
and so on, but when I type in something like:
find . -name *mobile*
I get the response:
zsh: no matches found: *mobile*
Why?
find . -name *mobile* # does not work
vs
find . -name '*mobile*' # works
The difference is due to the steps that the shell takes when it parses a line. Normally, the shell expands any wildcards it finds before it runs the command. However, the single quotes mark the argument as being a literal, which means that the shell does not perform wildcard expansion on that argument before running the command.
To demonstrate the difference, suppose you are in a directory with the following files:
$ tree
./
mobile.1
dir/
mobile.2
In the first case, without single quotes, zsh will process as follows:
expand the glob, rendering simply mobile.1 (because that is the only matching filename in the current directory
pass the result to find, hence:
find . -name mobile.1
So find will only look for files named literally mobile.1
In the second form, with single quotes, the entire glob will be preserved and passed to find:
find . -name *mobile*
Which means that find will look for any filename containing the string "mobile".
The important thing to note here is that both zsh and find support the same wildcard syntax; by using single quotes, you induce find to handle the wildcards in this case rather than zsh.
Turns out that all you have to do to solve the problem is add some quotes around the input:
find . -name '*mobile*'
I don't really have an answer as to why just yet...and the documentation doesn't have an something that sticks out to me, but let me know if you know the answer!
For archival purposes, here is my substantial edit/reformatting of #Swiss's response above. The edit queue has been full every time I tried to edit, for hours, so I want to preserve this for future reference. I hope it's deemed to be constructive.
To be super-clear it's a revision of another person's work.
find . -name *mobile* # does not work
vs
find . -name '*mobile*' # works
The difference is due to the steps that the shell takes when it parses a line. Normally, the shell expands any wildcards it finds before it runs the command. However, single quotes marks the argument as being a literal, which means that the shell does not preform wildcard expansion on that argument before running the command.
To demonstrate the difference, suppose you are in a directory with the following files:
$ tree
./
mobile.1
dir/
mobile.2
In the first case, without single quotes, zsh will process as follows:
expand the glob, rendering simply mobile.1 (because that is the only matching filename in the current directory
pass the result to find, hence:
find . -name mobile.1
So find will only look for files named literally mobile.1
In the second form, with single quotes, the entire glob will be preserved and passed to find:
find . -name *mobile*
Which means that find will look for any filename containing the string "mobile".
The important thing to note here is that both zsh and find support the same wildcard syntax; by using single quotes, you induce find to handle the wildcards in this case rather than zsh.

Find command to find Zip files with ignorecase

Can some one tell me how to use Find command to find files of extension Zip,ZIP,zip. ?
find . -iname *.zip is not working for me in AIX.
You need to uses quotes around the pattern matching part. So
find . -iname '*.zip'
will do fine.
assuming that your shell supports character classes as part of its wild-card processing, most do, try
find . -name '*.[Zz][Ii][Pp]'
-iname ? I don't know that one.
Yes, sorry, you need a starting directory, in this case the '.' that you have flagged as missing.
I hope this helps.

Resources