0

I have four files says - file1.txt, test2.txt, file23.txt, and tact24.txt and word/string to search in these files. If word found in one of file print filename.

Example:

word - cat

search cat in files - file1.txt test2.txt file23.txt tact24.txt

Suppose cat found in test2.txt then print only test2

Can this be done in one line via awk/sed commands?

I am trying below- but unable to get what i am expecting

grep cat file1.txt test2.txt file23.txt tact24.txt
file1.txt:cat
grep: test2.txt: No such file or directory
grep: file23.txt: No such file or directory
grep: tact24.txt: No such file or directory

grep cat file1.txt test2.txt file23.txt tact24.txt|grep -v "grep"
file1.txt:cat
grep: test2.txt: No such file or directory
grep: file23.txt: No such file or directory
grep: tact24.txt: No such file or directory

closed as unclear what you're asking by Sparhawk, Mr Shunz, Christopher, Michael Homer, jimmij Feb 14 at 0:26

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Pretty much exactly like this: stackoverflow.com/questions/16956810/… – Panki Feb 13 at 8:04
  • 4
    You quite obviously don't have those four files, only file1.txt. Also, in the title you say you want to print the filename, but in the question you say you want to print test2 if the string is found in test2.txt. What should be printed if the string is found in test2.doc? – Kusalananda Feb 13 at 8:08
1

To print the filename (without its filename suffix, if it has one) of the file that contains a given string:

awk '!found[FILENAME]++ && /string/ { fname = FILENAME; sub("\\.[^/]*$", "", fname); print fname }' file1.txt test2.txt file23.txt tact24.txt

This would detect the string string (used here as a regular expression, so special characters would have to be escaped) on any line in the current file, and if a match has not yet been found in that file, the filename without its filename suffix would be printed. The filename suffix is anything after the first dot in the filename. The way I have written the sub() command, it would retain the directory path of the file if this was given on the command line.

If you just want to output the pathname of the file, then use

grep -lF 'string' file1.txt test2.txt file23.txt tact24.txt

The -l option would make grep only output the pathnames of the files that contains matches, while -F would cause it to treat the string as a string and not as a regular expression.

If you give grep or awk filenames that don't exist, it will complain with errors. You may want to see these errors (as they indicate that something's wrong), or you may not. If you don't want to see them, then redirect them to /dev/null:

grep -lF 'string' file1.txt test2.txt file23.txt tact24.txt 2>/dev/null

The 2> means "redirect the standard error stream to the following location".

Instead of redirecting the error stream to /dev/null you could opt for using grep with the -s option:

grep -lsF 'string' file1.txt test2.txt file23.txt tact24.txt
  • 1
    Or, use the -s option with grep to silence it for nonexistent or unreadable files. – Rakesh Sharma Feb 13 at 8:38
  • perhaps grep -sFl 'string' file*.txt | sed 's/\.txt$//' to strip off the extension. – glenn jackman Feb 13 at 13:03
  • @glennjackman Filenames with newlines and sed being a line-oriented editor, and so on... – Kusalananda Feb 13 at 13:32

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