Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: In bash, check if any files matching type/name criteria exist in a directory

  1. #1

    In bash, check if any files matching type/name criteria exist in a directory

    I need to determine whether any files matching certain criteria are present in a specified directory.

    If it matters the criteria are:

    directories, the name of which ends in "_files"
    "regular" files, the name of which ends in ".html"
    "regular" files, the name of which ends in ".htm"

    I don't need to know how many there are or which types. I just need a simple binary logic response:

    yes, one or more files of one or more of these types of files is present in the directory specified.
    or
    no, no such files are present in the directory specified.

    The path/filename of the directory will be passed to the script in a variable and stuff I've already done will have established that the variable contains a valid directory path/filename.

    I am trying doing this with ls commands and putting the output in a variable, planning to somehow extract the first 50 characters or so of the variable to establish a new variable (I know, I am the spiritual descendant of Rube Goldberg) and checking if this matches the expected output in the event no such files are found but so far I've had no success. Right now I'm bogging down at the point of establishing a variable containing the output of an ls command. I've tried a lot of different nomenclatures with `s, (s, $s, "s, and 's in a remarkably large number of permutations, but so far it hasn't worked. I wonder if maybe the size of the output exceeds the permissable size of variables. Is there some way to send only the first 50 characters of so to the variable and ignore the rest? I've even started to tinker with the idea of sending the output of the command to a temporary text file, getting the variable from it, and deleting the file. I'm also wondering if I'm on the wrong track all together in trying to use the output of ls to do this. Any suggestions?
    Last edited by Dreamer Fithp Apprentice; April 22nd, 2013 at 11:11 PM. Reason: add [solved]

  2. #2
    Join Date
    Apr 2008
    Beans
    451
    Distro
    Kubuntu 10.04 Lucid Lynx

    Re: In bash, check if any files matching type/name criteria exist in a directory

    try the find command (man find) in conjunction with "-regex"

    example:
    find ~/MyDocuments -type f -regex .*_files$
    find ~/MyDocuments -type f -regex .*\.html$
    find ~/MyDocuments -type f -regex .*\.htm$

    ... and put this in a for loop:

    for file in $(find ~/MyDocuments -type f -regex .*_files$) ; do
    echo "file=[$file]" # this will just list the files it found
    done

    If the files contain whitespaces, you'll need to change $IFS or protect them with ""

  3. #3
    Join Date
    Feb 2007
    Location
    Romania
    Beans
    Hidden!
    Distro
    Ubuntu Development Release

    Re: In bash, check if any files matching type/name criteria exist in a directory

    Check out BashFAQ 004 (link in my signature).

    @ Lampi
    Please check out BashPitfalls 001 and BashFAQ 001.

  4. #4
    Join Date
    Mar 2008
    Beans
    1,219

    Re: In bash, check if any files matching type/name criteria exist in a directory

    Here's binary logic:
    Code:
    #!/bin/bash
    
    for pattern in ^d.*_files$ ^-.*\.html?$; do
    	# replace /path/to/folder with actual path and folder name 
    	ls -al /path/to/folder | grep -E $pattern >/dev/null && exit 1
    done
    
    exit 0
    Exit code ($?) will be 1 if anything is found or 0 otherwise. If you need output, convert to function (replace exit with return) and add some conditional echo.
    Last edited by prodigy_; April 21st, 2013 at 10:38 AM.

  5. #5
    Join Date
    Feb 2013
    Beans
    Hidden!

    Re: In bash, check if any files matching type/name criteria exist in a directory

    @prodigy_
    Why not just
    Code:
    /bin/ls -Alq /path/to/folder | egrep -q '^d.*_files$|^-.*\.html?$' && echo yep || echo nope
    or even (provided that none of the regular file names ends in _files/):
    Code:
    /bin/ls -Apq /path/to/folder | egrep -q '_files/$|\.html?$' && echo yep || echo nope


    @Lampi
    For binary logic you probably do not need the loop at all, just testing if the output of find is not empty should be enough:
    Code:
    [[
      -n $(
        find path/to/folder \( -type d -name \*_files -o -type f -regex '.*\.html?$' \) -printf found -quit
        )
    ]] && echo yep || echo nope
    Last edited by schragge; April 23rd, 2013 at 08:22 AM.

  6. #6
    Join Date
    Mar 2008
    Beans
    1,219

    Re: In bash, check if any files matching type/name criteria exist in a directory

    Quote Originally Posted by schragge View Post
    @prodigy_
    Why not just
    TBH, I just suggested an example solution w/o giving it much thought. But great job here, schragge! You actually made me remember a thing or two from find/ls manpages.

  7. #7

    Re: In bash, check if any files matching type/name criteria exist in a directory

    Thanks, guys. Talk about embarassment of riches. I'll study all of this, even if I get another one to work first.

  8. #8

    Re: In bash, check if any files matching type/name criteria exist in a directory

    Quote Originally Posted by schragge View Post
    @Lampi
    For binary logic you probably do not need the loop at all, just testing if the output of find is not empty should be enough:
    Code:
    [[
      -n $(
        find path/to/folder \( -type d -name \*_files -o -type f -regex '.*\.html?$' \) -printf found -quit
        )
    ]] && echo yep || echo nope
    I tried this first. The relevant portion of my script, including some tests and comments is:
    Code:
    # A test to make double sure of how $1 is set followed by Schragge's last method in post 5:
    echo "Dollar-mark1 expands to $1 on line 49 just before last method of Schragge in post 5." >> /media/wdsm3/script_testing/test.sh.output.txt
    [[
      -n $(
        find \"$1\" -maxdepth 1 \( -type d -name \*_files -o -type f -regex '.*\.html?$' \) -printf found -quit
        )
    ]] && echo "yep, some html components are present in $1."  >> /media/wdsm3/script_testing/test.sh.output.txt || echo "nope, no html components are present in $1."  >> /media/wdsm3/script_testing/test.sh.output.txt
    But, note presence of "folder_files" directory in ls output:
    Code:
    me@precise:~$ ls "/media/wdsm3/script_testing/test_  folder"
    file .txt              html_components                subdirectory
    folder_files           ordinary_file.txt              subdirectory with spaces
    folder_files,hacksaws  ordinary file with spaces.txt
    When I run the script against the same "test_ folder", I get this in test.sh.output.txt, the last two lines of which are the point:
    Code:
    test.sh begins processing another file here -----------------------
    /media/wdsm3/script_testing/test_  folder is dollar one.
    _variable_filename_end is set to folder
    Dollar-mark1 expands to /media/wdsm3/script_testing/test_  folder on line 49 just before last method of Schragge in post 5.
    nope, no html components are present in /media/wdsm3/script_testing/test_  folder.
    So, it isn't responding to "folder_files" as something that should elicit the "yep . . ." response. I tried removing the escape character prior to the *. Seperately, I tried replacing
    Code:
    -name \*_files
    with something modeled on the later part
    Code:
    -regex '.*\.html?$'
    I failed to save it but I think it was
    Code:
    -regex '.*_files?$'
    Still the same result. I have a lot of tinkering still to do and other expressions to try, but I thought, rather than one massive post, it would be clearer if I posted progress as I made it.

  9. #9
    Join Date
    Feb 2013
    Beans
    Hidden!

    Re: In bash, check if any files matching type/name criteria exist in a directory

    This
    Code:
    find \"$1\"
    should be
    Code:
    find "$1"
    Your folder contains spaces in its name. With your excessive quoting find sees it as two separate directories:
    Code:
    find '"/media/wdsm3/script_testing/test_' 'folder"'
    Since those directories don't exist, find ends with non-zero exit status.

  10. #10

    Re: In bash, check if any files matching type/name criteria exist in a directory

    Quote Originally Posted by schragge View Post
    This
    Code:
    find \"$1\"
    should be
    Code:
    find "$1"
    Your folder contains spaces in its name. With your excessive quoting find sees it as two separate directories:
    Code:
    find '"/media/wdsm3/script_testing/test_' 'folder"'
    Since those directories don't exist, find ends with non-zero exit status.
    Thanks, Schragge. I made that change and it works.

    I added the escaped quotes when plain $1 with no quotes didn't work. I need to study the effects of quotes. They trip me up more than anything. I thought I'd tried "$1" too but, unless I changed something else significant in the meantime, apparently not.

    But about the "unless", a strange thing happened to me on the way to the forum . . .
    I was trying your first and more general modification of Prodigy's suggestion
    Code:
    /bin/ls -Alq /path/to/folder | egrep -q '^d.*_files$|^-.*\.html?$' && echo yep || echo nope
    using an explicit path for testing, as I was suspecting problems with expansion of $1. In other words:
    Code:
    /bin/ls -Alq "/media/wdsm3/script_testing/test_  folder" | egrep -q '^d.*_files$|^-.*\.html?$' && echo "yep, probable html components are present in $1." >> /media/wdsm3/script_testing/test.sh.output.txt || echo "nope, nothing looking like an html component or associated file is present in $1" >> /media/wdsm3/script_testing/test.sh.output.txt
    and it worked correctly with 26 of the 27 test cases I had prepared but failed in the same way, reporting a false negative, with the same test file, a subdirectory named (at least apparently) "folder_files". So I made and tried "word_files" but that worked correctly, i.e., a positive yep response. So I looked real carefully at the name of the folder giving the problem and it sure looked like "folder_files" but I tried renaming it anyway, thinking maybe there is a character in there that looks like an underline but isn't, so I renamed it to "folder" and then renamed that back to "folder_files" and that fixed it. Now I wish I had moved the file and created a new test case from scratch because I can't reproduce the error. I tried " folder_files" (with a leading space) but that worked correctly. I don't think I CAN create a file with a trailing space. I don't know of any character that closely resembles any of those of "folder_files" but that is the only explanation I can think of. I don't think it can have been any attribute of the file other than name because I didn't replace the file, I renamed it. Anyway, both approaches are working for me now. And perhaps it is easier to believe that a dilettante scripter could get confused than that a "_" should fall from heaven, or something like that.

    Thanks, all. I'll mark this solved it the board will cooperate.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •