I have a directory pointed by g_inboundDir which contains following files: XAI-001-20170709-123456791.pdf YXAI-001-20170709-123456791.pdf 001-20170744-123456791.pdf

Variable g_filPfix="XAI" Variable g_fileExt=".pdf"

Now I want to pick each file which starts with XAI and process it for this I wrote the following command:

for i in `ls ${g_inboundDir}/* | grep -E '^${g_filPfix}-([0-9]{3})-([0-9]{8})-([0-9]{9})${g_fileExt}$' 2>/dev/null`

I was hoping to receive only XAI-001-20170709-123456791.pdf file but I am not getting any file.

  • 2
    Welcome to Unix & Linux! It is generally a really bad idea to parse the output of ls. You should probably look into either using find or simple shell globbing to get your list of files to process. Extensive further reading on the subject can be found here. – DopeGhoti Jul 11 '17 at 20:37
grep -E '^${g_filPfix}-([0-9]{3})-([0-9]{8})-([0-9]{9})${g_fileExt}$'

The immediate issue here is that the pattern for grep is wrapped in single quotes, so the shell will not expand the variables g_filPfix and g_fileExt. Replacing the quotes with double-quotes would fix that. (and you don't need the parenthesis in the pattern.)

Parsing the output of ls like that may be problematic with filenames that have whitespace or some odd characters. In particular, a filename with a space in the middle would be taken as two file names.

If you don't actually need such a strict pattern, you could just process all files with the given prefix and suffix:

for f in "$dir/$prefix"*"$suffix" ; do 
    somecmd "$f"

If you do need the strict pattern, some shells (like Bash, which you probably have on Linux) can do the regex match without external tools. So, to loop over all files in the directory and ignore the files that don't match the pattern:

for f in "$dir"/* ; do 
    [[ "$f" =~ "/$prefix"-[0-9]{3}-[0-9]{8}-[0-9]{9}"$suffix"$ ]] || continue
    somecmd "$f"

Don't parse ls.

for file in "${g_inboundDir}"/XAI*.pdf; do 
    things_to "$file"
  • things_to nice name for a user function ! :-) PS: @steeldriver seems to be right. – George Vasiliou Jul 11 '17 at 20:52
  • I have corrected the answer; good catch (: – DopeGhoti Jul 11 '17 at 21:03

Don't grep ls. Use find and regexp instead:

find ${g_inboundDir} -regextype sed -regex "^${g_filPfix}-([0-9]{3})-([0-9]{8})-([0-9]{9})${g_fileExt}$"

At the end you can use -exec to do something with those files.
Check man find to find out more about find :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.