I am trying to figure out a way to write a shell script that lists file names that start and end with certain characters/digit but also contain a certain string in the file.

So say the file name has to start with a digit and end with a character, but that file also has to contain "xyz". How would I work it out so that the result is just the name of the files.

The file names should be looked for in the current directory.

I know how to get them separately but I dont know how to combine the two together to get the proper outcome.

Example: List file names:
-starting with "F" and ending with a digit.
-contains "xyz" within the file.
File1 = "xyz"
File2 = "xYz"
File3 = "xyz"
tile4 = "xyz"
File = "xyz"

Here only File1 and File3 would be listed because they meet the criteria

  • 1
    Can you please add a concrete example showing what you already know and also some sample files and output?
    – Quasímodo
    Oct 8, 2020 at 22:00
  • For example the file has to start with "F" but end with any digit, but the file also has to contain "xyz". Example: File1 = "xyz". File2="xYz". File3="xyz". tile4="xyz". File="xyz". In this case only File1 and File3 will be outputted because they meet the requirements @Quasímodo Oct 8, 2020 at 22:09
  • Hang on. The filenames are File1 File2, etc... and the contents are xyz, correct? Making a list in the form filenames = content is very confusing, but the description seems clear enough. Thanks for the edit.
    – Quasímodo
    Oct 8, 2020 at 22:24

2 Answers 2

grep -l 'xyz' F*[0-9]

looks for xyz in every file whose name starts with "F" and ends with a digit. The -l swtich makes Grep suppress the matching lines and only report the matching files.

  • Thanks for your help, sorry about the confusion. Oct 9, 2020 at 0:37
find . -name "F*[[:digit:]]" | while read line; do 
    grep -q xyz $line 
    if [ $? -eq 0 ]; then 
        echo $line 
    fi;  done

The above code will find files in the current directory that starts with F and ends with a digit. It will then loop over each file that passes the find criterion, and each iteration will perform grep in the file to find the string xyz. The grep output is not printed out because of -q. It will then check the error status of the grep command. If there was a match in the file, grep returns 0, so the echo $line will be executed. Here, $line refers to the file that was found from the find command that has been piped into the while part. If grep returned no match, it will return 1, so echo $line will not be run.

  • 2
    Find will look in subdirectories too. The variables should be quoted and this will unfortunately fail for weird file names. Better to use -exec if really going this route.
    – Quasímodo
    Oct 8, 2020 at 22:35

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.