Extract IP Address with grep - search

I have outputted the IPTables log to another log file,
/var/log/iptableftp.log
Within that file it displays the full iptables log line, Is there a way to search the /var/log/iptableftp.log file I previously made and search for SRC= and removing everything thats before and after and just leaving the IP address behind?

you should have a look at sed
cat iptables.log | sed -e 's/SRC=([0-9\.]+).*/$1/g'
sed uses regex in to form: s/exp_to_find/replace_with/g
Edited to fix arg in replace expression, thx to Ed Morton

Related

grepping text string returns no result

I have to find a lot of information in the esxi host for configuration.
When I run commands like:
# grep -i "^Banner" /etc/ssh/sshd_config
I get no results but if I execute:
cat /etc/ssh/sshd_config
I can see in file the string "Banner /etc/issue".
Why does grep not return the information requested? What am I missing?
I would experiment with the searched file a bit.
Please try the following command:
cat /etc/ssh/sshd_config | grep -i '^Banner'
Or if it fails just
cat /etc/ssh/sshd_config | grep -i Banner
(the word 'banner' anywhere).
Further please try to copy the file to your local repository
and try examining with vi sshd_config to test if there aren't any non-visible characters in the file making the search insufficient.
It could be the hidden characters in the file, or that the searched string isn't located at start of the line (or combination of both.)

How to replace an unknown IP address in a specific line of a text file

How can I apply this sed command to a specific line in a text file instead of to the entire file?
I found a solution here for replacing any IP addresses in a file with a specific address. I need to apply this command to a specific line in the file so that it only replaces one single unknown IP address. I saw that sed uses -n to filter but I literally know nothing about how to apply this to achieve my goal.
This code works for every IP in the file:
sed -e 's/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/x.x.x.x/g' test.txt
How can I apply it to the only line in the file that also includes the string, "ipv4" so that other lines containing IP addresses are left unmodified?
With sed, you can use a regex as an address like this:
sed -re '/ipv4/s/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/x.x.x.x/g' test.txt
If you don't specify -r, you'll need to escape the braces, i.e.:
sed -e '/ipv4/s/[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}/x.x.x.x/g' test.txt
You can skip over uninteresting lines:
sed '/ipv4/!b;s/YOUR PATTERN HERE/YOUR IP HERE/' input
If I get it right you want to find the first occurrence of the ip address on a line that also contains ipv4, and skip all other occurrences.
With GNU sed, try
sed -i -E '/ipv4/{s/[0-9]{1,3}(\.[0-9]{1,3}){3}/x.x.x.x/g;T;:a;n;ba}' test.txt
The -E will enable POSIX ERE syntax, no need to escape {} and (). The -i will replace inline in the file directly. /ipv4/ will find a line with ipv4 on it, and then {s/[0-9]{1,3}(\.[0-9]{1,3}){3}/x.x.x.x/g;T;:a;n;ba} will do the replacement only on that line. See potong's explanation of the T;:a;n;ba here
If you have a POSIX sed, try
sed -e '/ipv4/ {' -e 's/[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}/x.x.x.x/g' -e ':a' -e n -e 'ba' -e '}' file > newfile

How to replace text strings (by bulk) after getting the results by using grep

One of my Linux MySQL servers suffered from a crash. So I put back a backup, however this time the MySQL is running local (localhost) instead of remotely (IP-address).
Thanks to Stack Overflow users I found an excellent command to find the IP-address in all .php files in a given directory! The command I am using for this is:
grep -r -l --include="*.php" "100.110.120.130" .
This outputs the necessary files with its location ofcourse. If it were less than 10 results, I would simply change them by hand obviously. However I received over 200 hits/results.
So now I want to know if there is a safe command which replaces the IP-address (example: 100.110.120.130) with the text "localhost" instead for all .php files in the given directory (/var/www/vhosts/) recursively.
And maybe, if only possible and not to much work, also output the changed lines to a file? I don't know if thats even possible.
Maybe someone can provide me with a working solution? To be honest, I dont dare to fool around out of the blue with this. Thats why I created a new thread.
The most standard way of replacing a string in multiple files would be to use a tool such as sed. The list of files you've obtained via grep could be read line by line (when output to a file) using a while loop in combination with sed.
$ grep -r -l --include="*.php" "100.110.120.130" . > list.txt
# this will output all matching files to list.txt
Replacing IP in matched files:
while read -r line ; do echo "$line" >> updated.txt ; sed -i 's/100.110.120.130/localhost/g' "${line}" ; done<list.txt
This will take list.txt and read it line by line to the sed command which should replace all occurrences of the IP to "localhost". The echo command directly before sed outputs all the filenames that will be modified into a file updated.txt (it isn't necessary though as list.txt contains the same exact filenames, although it could be used as a means of verification perhaps).
To do a dry run before modifying all of the matched files remove the
-i from the sed command and it will print the output to stdout
instead of in-place modifying the files.

shell script grep only working on last line of file

I have a very strange problem I've never encountered and could not find anything related on other posts here, I have a shell script that just greps a test host file(will use real one once this works) in a while loop but it will only output the last line:
#!/bin/bash
while read line
do
grep $line /etc/test/hosts
done < temp-file.txt
here is the /etc/test/hosts file:
device1 192.168.0.1
device2 192.168.0.2
device3 192.168.0.3
// cut
device50 192.168.0.50
the temp-file.txt is identical to the test host file for testing
And as mentioned, here is the output - only showing last line:
device3 192.168.0.50
If I change the grep command to just echo $line it outputs correctly. I have tried changing the number of lines in the test host file to be more and less but same result. I have also done the grep command from cli and it works fine on every device I grep for. I have also tried putting the $line in double quotes but that also has not changed anything.
I have also tried an alternate while loop using the while IFS="\n" method but same results. This seems like it should be extraordinarily simple but I'm having issues. Am I doing something wrong or is this maybe a bug in bash?
question answered by Eric Renouf via comment.
solution:
add sed -i 's/\r$//' temp-file.txt to top of script to remove the \r that were at the end of each line.

How do I add a line of text to the middle of a file using bash?

I'm trying to add a line of text to the middle of a text file in a bash script. Specifically I'm trying add a nameserver to my /etc/resolv.conf file. As it stands, resolv.conf looks like this:
# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3
My goal is to add nameserver 127.0.0.1 above all other nameserver lines, but below any text above that. In the end I want to my resolve.conf file to look like this:
# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3
How is this possible via a bash script? Is this something sed or awk can do? Or would creative greping to recreate the file be my best move?
Here is a solution using sed:
$ sed -n 'H;${x;s/^\n//;s/nameserver .*$/nameserver 127.0.0.1\n&/;p;}' resolv.conf
# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3
How it works: first, suppress the output of sed with the -n flag. Then, for each line, we append the line to the hold space, separating them with newlines:
H
When we come to the end of the file (addressed by $) we move the content of the hold space to the pattern space:
x
If the first line in pattern space is blank we replace it with nothing.
s/^\n//
Then we replace the first line starting with nameserver by a line containing nameserver 127.0.0.1, a new line (Your version of sed may not support \n, in which case replace the n with a literal newline) and the original line (represented by &):
s/nameserver .*$/nameserver 127.0.0.1\n&/
Now we just need to print the results:
p
Assuming you want to insert immediately after the search line, this is much simpler:
sed -ie '/^search/a nameserver 127.0.0.1' filename
-i : edit file in place
-e : allows the execution of a script/commands inside sed expression
a mynewtext : command that tells sed to insert the text mynewtext after matched pattern
awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'
How about something like:
sed -e ':a;N;$!ba;s/nameserver/nameserver 127.0.0.1\nnameserver/' /etc/resolv.conf
(similar to this: sed: Find pattern over two lines, not replace after that pattern)
Here's a Perl solution:
perl -lne 'if (not $f and /^nameserver/){ print "nameserver 127.0.0.1"; $f=1 }; print' resolv.conf
-n loop around every line of the input file, do not automatically print every line
-l removes newlines before processing, and adds them back in afterwards
-e execute the perl code
$f is used as a flag to indicate that the nameserver string has already been found
This might work for you:
sed -e '/nameserver/{x;/./b;x;h;i\nameserver 127.0.0.1' -e '}' resolv.conf
Or GNU sed:
sed -e '0,/nameserver/{//i\nameserver 127.0.0.1' -e '}' resolv.conf

Resources