finding the string within folder using shell command - bash

How to find all files within folder containing specific text (string) if text found return 1 if not return 0 in linux?
grep -r "34161FA8203289722240CD40" /usr/lib/cgi-bin/ParkingSoft/api/v3/LaneApi/ETC/MywebSocket /*.txt

Try This:
grep -rwl 'PATH/targetFolder/' -e 'target_string' | awk -F "/" '{print $NF}'
The above command returns the name of all files that contains the target_string.
To know about -rwl check this answer, However awk -F "/" '{print $NF}' just split the grep output and return the last part. (file name in your case)

The -q option returns (exit code) 1 when no match is found. Try:
echo "string" | grep -q in && echo yes
echo "string" | grep -q out && echo yes
In your case:
searchdir="/usr/lib/cgi-bin/ParkingSoft/api/v3/LaneApi/ETC/MywebSocket "
if [ ! -d "$searchdir" ]; then
echo "Check searchdir. Is 'ETC' really in uppercase and is `Mywebsocket ` including a space?"
else
if grep -rwq '34161FA8203289722240CD40' "${searchdir}/*.txt; then
echo "String found in one of the files."
fi
fi

Related

How to test if an attribute exists in a file with Bash?

I'm trying to get this tested, but I'm not sure if the if is right
if [ $(lsattr /mnt/backup/*.* | grep i) ] ;
then
echo "file $_ has i attribute";
else
echo "file $_ does not have i attribute"
fi
This is the lsattr on that directory:
----i----------------- /mnt/backup/Backup-Full_02-04-2022.7z
---------------------- /mnt/backup/test.7z
Thank you
With grep i you will also match file names containing i. Moreover, $_ is not set so its value is probably just the empty string. If you really want to use an if statement you also need a loop. And grep is not needed any more if you use the bash conditional expressions:
$ lsattr /mnt/backup/*.* | while read -r attr name; do
if [[ "$attr" == "*i*" ]]; then
echo "file $name has i attribute"
else
echo "file $name does not have i attribute"
fi
done
file /mnt/backup/Backup-Full_02-04-2022.7z has i attribute
file /mnt/backup/test.7z does not have i attribute
If you can use awk instead of grep you can easily limit the search to the first word:
awk '$1 ~ "i"'
And you don't need any bash if or while loop any more, all this can be embedded in the awk script:
$ lsattr /mnt/backup/*.* | awk -vs1=" has " -vs2=" does not have " \
'{print $2 ($1 ~ "i" ? s1 : s2) "i attribute"}'
file /mnt/backup/Backup-Full_02-04-2022.7z has i attribute
file /mnt/backup/test.7z does not have i attribute

How to match a folder name and use it in an if condition using grep in bash?

for d in */ ; do
cd $d
NUM = $(echo ${PWD##*/} | grep -q "*abc*");
if [[ "$NUM" -ne "0" ]]; then
pwd
fi
cd ..
done
Here I'm trying to match a folder name to some substring 'abc' in the name of the folder and check if the output of the grep is not 0. But it gives me an error which reads that NUM: command not found
An error was addressed in comments.
NUM = $(echo ${PWD##*/} | grep -q "*abc*"); should be NUM=$(echo ${PWD##*/} | grep -q "*abc*");.
To clarify, the core problem would be to be able to match current directory name to a pattern.
You can probably simply the code to just
if grep -q "*abc*" <<< "${PWD##*/}" 2>/dev/null; then
echo "$PWD"
# Your rest of the code goes here
fi
You can use the exit code of the grep directly in a if-conditional without using a temporary variable here ($NUM here). The condition will pass if grep was able to find a match. The here-string <<<, will pass the input to grep similar to echo with a pipeline. The part 2>/dev/null is to just suppress any errors (stderr - file descriptor 2) if grep throws!
As an additional requirement asked by OP, to negate the conditional check just do
if ! grep -q "*abc*" <<< "${PWD##*/}" 2>/dev/null; then

bash: sed: unexpected behavior: displays everything

I wrote what I thought was a quick script I could run on a bunch of machines. Instead it print what looks like might be directory contents in a recursive search:
version=$(mysql Varnish -B --skip-column-names -e "SELECT value FROM sys_param WHERE param='PatchLevel'" | sed -n 's/^.*\([0-9]\.[0-9]*\).*$/\1/p')
if [[ $(echo "if($version == 6.10) { print 1; } else { print 0; }" | bc) -eq 1 ]]; then
status=$(dpkg-query -l | awk '{print $2}' | grep 'sg-status-polling');
cons=$(dpkg-query -l | awk '{print $2}' | grep 'sg-consolidated-poller');
if [[ "$status" != "" && "$cons" != "" ]]; then
echo "about to change /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm"; echo;
cp /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm.bkup;
sed -ir '184s!\x91\x93!\x91\x27--timeout=35\x27\x93!' /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm;
sed -n 183,185p /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm; echo;
else
echo "packages not found. Assumed to be not applicable";
fi
else
echo "This is 4.$version, skipping";
fi
The script is supposed to make sure Varnish is version 4.6.10 and has 2 custom .deb packages installed (not through apt-get). then makes a backup and edits a single line in a perl module from [] to ['--timeout=35']
it looks like its tripping up on the sed replace one liner.
There are two major problems (minor ones addressed in comments). The first is that you use the decimal code for [] instead of the hexa, so you should use \x5b\x5d instead of \x91\x93. The second problem is that if you do use the proper codes, sed will still interpret those syntactically as []. So you can't escape escaping. Here's what you should call:
sed -ri'.bkup' '184s!\[\]![\x27--timeout=35\x27]!' /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm
And this will create the backup for you (but you should double check).

How can I check if 'grep' doesn't have any output?

I need to check if the recipient username is in file /etc/passwd which contains all the users in my class, but I have tried a few different combinations of if statements and grep without success. The best I could come up with is below, but I don't think it's working properly.
My logic behind it is that if the grep is null, the user is invalid.
send_email()
{
message=
address=
attachment=
validuser=1
until [ "$validuser" = "0" ]
do
echo "Enter the email address: "
read address
if [ -z grep $address /etc/passwd ]
then
validuser=0
else
validuser=1
fi
echo -n "Enter the subject of the message: "
read message
echo ""
echo "Enter the file you want to attach: "
read attachment
mail -s "$message" "$address"<"$attachment"
done
press_enter
}
Just do a simple if like this:
if grep -q $address /etc/passwd
then
echo "OK";
else
echo "NOT OK";
fi
The -q option is used here just to make grep quiet (don't output...)
Use getent and check for grep's exit code. Avoid using /etc/passwd. Equivalent in the shell:
getent passwd | grep -q valid_user
echo $?
Output:
0
And:
getent passwd | grep -q invalid_user
echo $?
Output:
1
Your piece of code:
if [ -z grep $address /etc/passwd ]
You haven't saved the results of grep $address /etc/passwd in a variable. Before putting it in the if statement and then testing the variable to see if it is empty.
You can try it like this:
check_address=`grep $address /etc/passwd`
if [ -z "$check_address" ]
then
validuser=0
else
validuser=1
fi
The -z check is for variable strings, which your grep isn't giving. To give a value from your grep command, enclose it in $():
if [ -z $(grep $address /etc/passwd) ]
The easiest one will be this:
cat test123
# Output: 12345678
cat test123 | grep 123 >/dev/null && echo "grep result exist" || echo "grep result doesn't exist"
# Output: grep result exist
cat test123 | grep 999 >/dev/null && echo "grep result exist" || echo "grep result doesn't exist"
# Output: grep result doesn't exist
My problem was that the file I was trying to grep was a binary file. On windows, the first two characters in the file were little squares. On mac, the first two characters were question marks. When I used more or less on the file, I could see it was binary and when I used diff, it responded that the "Binary files foo.log and requirements.txt differ".
I used cat to display the contents of the file, highlighted and copied the text (minus the two question marks at the top, deleted the file, created a new file with touch and then used vi to paste the text back into the new file.
After that, grep worked fine.
Shorter:
until ! grep $address /etc/passwd ; do {
do_your_stuff
}

if variable exists in col 1 of a file, set a separate variable equal to the corresponding value in col 2

I'm writing a script to run a grep for an input, create a file list and grep that file list in a separate directory and print the results.
echo "enter term"
read term
grep -rc "$term" /prod/directory1 | grep -v ":0" | sed -s 's%:[0-9]*%%' > file_list.txt
grep -rl --file=file_list.txt /tmp/directory2 > results.txt
but i would like to add an if statement that will identify if the $term is equal to a value in the first column of another file, and then set a new variable to the corresponding value in column 2 of that file.
echo "enter term"
read term
for i in products.txt; do
if [[ $term = $i ]]; then
var2 = $2
echo "product code set to: "$var2
else
var2 = 0
echo "product code set to 0."
fi
done
grep -rc "$term" /prod/directory1 | grep -v ":0" | sed -s 's%:[0-9]*%%' > file_list.txt
if [[ ! $var2 = 0 ]] ; then
grep -rc "var2" /prod/directory1 | grep -v ":0" | sed -s 's%:[0-9]*%%' >> file_list.txt
sed -s 's%.properties%%' file_list.txt | sort -u > file_list.txt
grep -rl --file=file_list.txt /tmp/directory2 > results.txt
the new grep will return results with .properties at the end, so I remove them and also any duplicate files from the list. Below is a sample for products.txt
Product_1 productCode_1
Product_2 productCode_2
Product_3 productCode_3
I would like the script to identify whether $term is in column one of that file, and then set $var2 equal to the corresponding productCode in column two. I believe once that variable is set everything else will work out nicely but right now it fails at:
for i in products.txt; do
if [[$term = $i ]]; then
var2 = $2
Thanks in advance for the assistance, I'm relatively new to bash scripting so I apologize in advance for my ineptitude.
Try:
var2=$(awk -v term="Product_2" '$1==term{print $2}' products.txt)
Change Product_2 to read from another variable, if required.

Resources