I am currently learning bash scripting, wanted help in following issue.
There are 3 files containing list of file paths inside them: list1, list2, list3.
list1
contains paths of multiple txt paths.
list2
contains paths of multiple cfg paths.
list3
contains paths of multiple bat paths.
Example:
list1:
./saved/nametxts/ptboy1.txt
./saved/nametxts/ptboy2.txt
./saved/nametxts/ppboy1.txt
./saved/nametxts/ppboy2.txt
./saved/nametxts/pgboy_a.txt
list2:
./saved/configs/names/ptboy1.cfg
./saved/configs/names/ptboy2.cfg
./saved/configs/names/ppboy1.cfg
./saved/configs/names/ppboy2.cfg
./saved/configs/names/pgboy_a.cfg
list3:
./saved/batches/confignames/ptboy1.bat
./saved/batches/confignames/ptboy2.bat
./saved/batches/confignames/ppboy1.bat
./saved/batches/confignames/ppboy2.bat
./saved/batches/confignames/pgboy_a.bat
I want to grep for
a name John from the files listed in list1
an ID HS_J_1024 from files listed in list2 and
profile history hist_1024 from files listed in list3
Hence, from the above example,
John is searched in ./saved/nametxts/ptboy1.txt
and other following textfiles from list1
HS_J_1024 is searched in ./saved/configs/names/ptboy1.cfg
and other following cfgfiles from list2
hist_1024 is searched in ./saved/batches/confignames/ptboy1.bat
and other following batfiles from list3
User will give only path for these lists, such as:-
./saved/namelists/list1
./saved/cfglists/list2
./saved/batlists/list3
Then grep for name, ID and profile in all the files one by one.
Once name, ID, profile matches - the Bat file would get updated with:
"grepped today " at the end of batfile
.
What I have tried now:
#!/bin/bash
read -p "Enter name list file path: " filename
read -p "Enter CFG list file path: " filecfg
read -p "Enter bat list file path: " filebat
echo $filename
echo $filecfg
echo $filebat
#making one line through paste
paste $filename $filecfg $filebat > pastefile
#awk -F ' ' '{print $1 ":" $2}' pastefile
#file="pastefile"
while IFS= read -r line; do
echo "$line" > printline
#there are 3 parts (filepaths) - storing them one by one in a1(names), a2(cfg), a3(bat)
awk '{print $1}' printline > a1
awk '{print $2}' printline > a2
awk '{print $3}' printline > a3
chmod +x a1,a2,a3
echo "grep -A 2 'John' a1 | sed 's?.............\$??' > a11" > a11
echo "grep 'HS_J_1024' a2 > a12" > a12
echo "grep 'hist_1024' a3 | sed -i 's?\$?grepped today?' a3" > a13
chmod +x a11,a12,a13
./a11
./a12
./a13
done <pastefile
Here files a1, a2, a3 are having proper file paths but the same is not reflecting when I try to grep. I am missing something to make this an input to the grep.
Could you please help me out? I would grateful if you could suggest any other optimal way of doing this too.
Thank you
Note: searching in the files listed in list1, list2 and list3, not in list1, list2 and list3 themselves.
If, as in your example, your file names do not contain white spaces, you can try:
read -p "Enter name list file path: " filename
read -p "Enter CFG list file path: " filecfg
read -p "Enter bat list file path: " filebat
read -p "Enter first string to search for: " s1
read -p "Enter second string to search for: " s2
read -p "Enter third string to search for: " s3
while read -r a1 a2 a3; do
if grep -qF "$s1" "$a1" && grep -qF "$s2" "$a2" && grep -qF "$s3" "$a3"; then
printf 'grepped today\n' >> "$a3"
fi
done < <(paste "$filename" "$filecfg" "$filebat")
If your file names can indeed contain white spaces you can store the content of your 3 files in bash arrays with mapfile
and use these arrays in your loop:
mapfile -t l1 < "$filename"
mapfile -t l2 < "$filecfg"
mapfile -t l3 < "$filebat"
for (( i=0; i<${#l1[@]} && i<${#l2[@]} && i<${#l3[@]}; i++ )); do
if grep -qF "$s1" "${l1[i]}" && grep -qF "$s2" "${l2[i]}" && grep -qF "$s3" "${l3[i]}"; then
printf 'grepped today\n' >> "${l3[i]}"
fi
done