2014GAM
2014GAM

Reputation: 103

Print all file names and append 1 to each name if there is a particular string else append 0

I have multiple files inside a folder and I want to scan the contents of each file to check for a string e.g. "abc" (case sensitive). I want to output the file name as well as the string with a label like 1 or 0 to tell if the string was present or not. E.g. if there are files

A1
A2
B3
B5
C8
Z7

and only B3 and C8 contain "abc" . The output should be as follows

A1 abc 0
A2 abc 0
B3 abc 1
B5 abc 0
C8 abc 1
Z7 abc 0

All this should be printed into a "output.txt" file.

My code seems to work :

#!/bin/bash
touch output.txt
for f in * ; 
do echo ${f} ;
 echo "abc" ;
 grep -w "abc" ${f}| wc -l ;
done

The output is like

A1 
abc 
0
A2 
abc 
0
B3 
abc 
1
B5 
abc 
0
C8 
abc 
1
Z7 
abc 
0

However, I am unable to print them into the txt file, also not able to do it in the order I want. Kindly advise.

Edit : I cd into the directory containing the files and the txt file is in an outside root directory.

Edit 2 : This is not similar to "echo -n" prints "-n" as, I want to use grep to print out file names while simultaneously adding labels depending on the presence/absence of a particular string

Upvotes: 1

Views: 491

Answers (4)

hek2mgl
hek2mgl

Reputation: 158130

You can use find and grep:

find -maxdepth 1 -type f  -printf "%p abc " \
     -exec grep -q abc {} \; -printf "1\n" -o -printf "0\n"

Upvotes: 1

M. Nejat Aydin
M. Nejat Aydin

Reputation: 10133

A one-liner using GNU grep and sed:

grep -m1 -cw abc * | sed -E 's/:(.)$/ abc \1/'

Upvotes: 2

user1934428
user1934428

Reputation: 22301

I would do it like this:

word=abc
for f in *
do
  grep -vqswF "$word" "$f"
  label=$?
  echo "$f $word $label"
done

-v makes the exit code of grep to be 1 if the word is not in the file, 0 if it is. -q ensures that grep does not output anything to stdout. In my example, I also used -s which supresses error messages from unreadable files. You don't have to use this, but errors like this will show up in the exit code (usually 2 in such a case). -F ensures that your code will still work if you set the word to something containing special characters for grep.

Upvotes: 2

tripleee
tripleee

Reputation: 189739

If you have a single string, grep -l could do what you want with a bit of postprocessing, but the most straightforward solution will be Awk.

awk -v str="abc" 'FNR == 1 {
    if (!p) print f, str, 0; f = FILENAME; p=0 }
0 ~ str { print f, str, 1; p = 1; nextfile }
END { if (!p) print f, str, 0 }' * >output.txt

Recall that Awk processes the entire script for each input line and evaluates the conditions. FNR, the input line number, is 1 when you start processing a new fils, we check if there is data from a previous file which needs to be printed, then initialize a couple of variables for the current file. If we see the search string, we print and close the current file. When we reach the end of all files, chech again if something from the last file still needs to be printed.

Upvotes: 1

Related Questions