Use Bash to Read File Then Do "grep" with The Line Against The File Itself - linux

I am trying to read a file using Linux Bash and then use "grep" to run that line against the file itself. It seems not working to me...
#!/bin/bash
path=$1
while read line
do
var1=$(grep $line $path)
echo $?
exit
done < $path
The $? returns 1. What's going on here?

Use grep -F (fixed string) instead:
var1=$(grep -F "$line" "$path")

Related

While loop with sed

I have the following code but it doesnt work when i execute the code, the file th2.csv its empty.
The function of the sed is replace two words. I dont know how to make the script work correctly.
It must be done with the while.
bash th1.csv > th2.csv
Script bash
#!/bin/bash
while read -r line; do
echo "$line" | sed -E "s/,True,/,ll,/g;s/,False,/,th,/" th1.csv
done < th1.csv
Given the requirements that you must loop and apply regex, line by line, then consider:
#!/bin/bash
while read -r line; do
echo "$line" | sed -E "s/,True,/,ll,/g;s/,False,/,th,/" >> th2.csv
done < th1.csv
This reads, line by line, via a while loop. Each line is passed as stdin to sed. Note we remove the th1.csv at the end of your original sed attempt, as that will override sed reading from stdin (causing it to ignore it and instead process the file over and over again, every iteration). Lastly we append >> to your th2.csv file each iteration.
Guessing a step ahead, that you may want to pass the two files in as parameters to the script (just based on your first code snippet) then you can change this to:
#!/bin/bash
while read -r line; do
echo "$line" | sed -E "s/,True,/,ll,/g;s/,False,/,th,/" >> "$2"
done < "$1"
And, assuming this script is called myscript.sh you can call it like:
/bin/bash myscript.sh 'th1.csv' 'th2.csv'
Or, if you make it executable with chmod +x myscript.sh then:
./myscript.sh 'th1.csv' 'th2.csv'.

trying to read every line in file, output always 'cat $file'

I am trying to display every line of a file in the terminal but the output is always:
cat $file
this is my code:
#!/bin/bash
file="users.csv"
IFS=''
echo "bobama, Barack Obama" > $file
echo "gbush, George Bush" >> $file
for line in `cat $file`;
do
echo $line;
done
I solved it by replacing 'cat $file' with $(cat $file).
You can find a better explanation here:
Why can't you use cat to read a file line by line where each line has delimiters

replacement in a file only in a fixed line

I am writing a shell script in which I will read a file and will modify it.
there will be occurrence of some string "ABC_1" in multiple lines.
I need to replace it with "XYZ_1" only when there is "OPQ_3" also present in the line else there should be no modification in the line.
please help how can I do replacement if I read a file liken by line.
for FILE in $FILES
do
echo $FILE
while read line
do
if grep -n "OPQ_3" $line
then
sed -i 's/ABC_1/XYZ_2/'
fi
done < $FILE
done
You can use this sed:
sed -i '/OPQ_3\|OPQ_4/s/ABC_1/XYZ_2/' file
Anubhava has the better answer. Here's how you'd write it in bash
for file in $FILES; do
echo "$file"
tmpfile=$(mktemp)
while IFS= read -r line; do
[[ $line == *OPQ_3* ]] && line=${line/ABC_1/XYZ_2/}
echo "$line"
done < "$file" > "$tmpfile"
mv "$tmpfile" "$file"
done
Note IFS= read -r line is the only way to read a line from stdin exactly, without losing any whitespace or special characters.

Removing lines matching a pattern

I want to search for patterns in a file and remove the lines containing the pattern. To do this, am using:
originalLogFile='sample.log'
outputFile='3.txt'
temp=$originalLogFile
while read line
do
echo "Removing"
echo $line
grep -v "$line" $temp > $outputFile
temp=$outputFile
done <$whiteListOfErrors
This works fine for the first iteration. For the second run, it throws :
grep: input file ‘3.txt’ is also the output
Any solutions or alternate methods?
The following should be equivalent
grep -v -f "$whiteListOfErrors" "$originalLogFile" > "$outputFile"
originalLogFile='sample.log'
outputFile='3.txt'
tmpfile='tmp.txt'
temp=$originalLogFile
while read line
do
echo "Removing"
echo $line
grep -v "$line" $temp > $outputFile
cp $outputfile $tmpfile
temp=$tmpfile
done <$whiteListOfErrors
Use sed for this:
sed '/.*pattern.*/d' file
If you have multiple patterns you may use the -e option
sed -e '/.*pattern1.*/d' -e '/.*pattern2.*/d' file
If you have GNU sed (typical on Linux) the -i option is comfortable as it can modify the original file instead of writing to a new file. (But handle with care, in order to not overwrite your original)
Used this to fix the problem:
while read line
do
echo "Removing"
echo $line
grep -v "$line" $temp | tee $outputFile
temp=$outputFile
done <$falseFailures
Trivial solution might be to work with alternating files; e.g.
idx=0
while ...
let next='(idx+1) % 2'
grep ... $file.$idx > $file.$next
idx=$next
A more elegant might be the creation of one large grep command
args=( )
while read line; do args=( "${args[#]}" -v "$line" ); done < $whiteList
grep "${args[#]}" $origFile

Bash Script : Unwanted Output

I have this simple bash script:
I run ns simulator on each file passed in argument where last argument is some text string to search for.
#!/bin/bash
nsloc="/home/ashish/ns-allinone-2.35/ns-2.35/ns"
temp="temp12345ashish.temp"
j=1
for file in "$#"
do
if [ $j -lt $# ]
then
let j=$j+1
`$nsloc $file > $temp 2>&1`
if grep -l ${BASH_ARGV[0]} $temp
then
echo "$file Successful"
fi
fi
done
I expected:
file1.tcl Successful
I am getting:
temp12345ashish.temp
file1.tcl Successful
When i run the simulator command myself on the terminal i do not get the file name to which output is directed.
I am not getting from where this first line of output is getting printed.
Please explain it.
Thanks in advance.
See man grep, and see specifically the explanation of the -l option.
In your script (above), you are using -l, so grep is telling you (as instructed) the filename where the match occurred.
If you don't want to see the filename, don't use -l, or use -q with it also. Eg:
grep -ql ${BASH_ARGV[0]} $temp
Just silence the grep:
if grep -l ${BASH_ARGV[0]} $temp &> /dev/null

Resources