Search and replace URL in all files - linux

I'm looking to run script or command to mass change a string that is a URL. I've viewed many examples on this forum, however none are working.
I have created a .sh file to run the following:
$SRC='$url = "https://www.myurl.com/subdir/process.do"';
$DST='$url="https://api.myurl.com/subdir/process.do"';
find . -type f -name "*.php" -exec sed -i 's/$SRC/$DST/g' {} +;
This is not working. I'm thinking it may because of having backslashes in the search content? The search/replace is needed to be run across all sub-directories on .php files.
Any assistance would be greatly appreciated.
Thanks!

First thing - check your variable definitions. In bash, variable definitions usually do not start with a leading $. Ie, should be:
SRC='$url = "https://www.myurl.com/subdir/process.do"';
DST='$url="https://api.myurl.com/subdir/process.do"';
Next, you should switch to using single quotes for the pattern, and double quotes for the variable, as per:
https://askubuntu.com/questions/76808/how-do-i-use-variables-in-a-sed-command
Example that seems to work:
sed -i 's,'"$SRC"','"$DST"','
UPDATE: This exact script works perfectly for me on Linux:
#!/bin/bash
SRC='$url = "https://www.myurl.com/subdir/process.do"';
DST='$url="https://api.myurl.com/subdir/process.do"';
find . -type f -name "*.php" -exec sed -i 's,'"$SRC"','"$DST"',' {} \;
Contents of file "asdf.php" created in home directory (before running script):
$url = "https://www.myurl.com/subdir/process.do"
Contents of file "asdf.php" after running script:
$url="https://api.myurl.com/subdir/process.do"

Related

Simple Bash Script that recursively searches in subdirs for a certain string

i recently started learning linux because a ctf contest is coming in the next months. The problem that I struggle with is that i am trying to make a bash script that starts from a directory, checks if the content is a directory or other kind of file. If it is a file,image etc apply strings $f | grep -i 'abcdef', if it is a directory cd to that directory and start over. i have c++ experience and i understand the logic but i can't really make it work.I can't succesfully implement the loop that goes thru all the subdirectories. All help would be appreciated!
you don not need a loop for this implementation. The find command can do what you are looking after.
for instance:
find /home -type f -exec sh -c " strings {} | grep abcd " \;
explain:
/home is you base directory can be anything
-type f: means a regular file
-exec from the man page:
"Execute command; true if 0 status is returned. All
following arguments to find are taken to be arguments to
the command until an argument consisting of ;' is encountered. The string {}' is replaced by the current
file name being processed everywhere it occurs in the
arguments to the command, not just in arguments where it
is alone, as in some versions of find. Both of these
constructions might need to be escaped (with a `') or
quoted to protect them from expansion by the shell. See
the EXAMPLES section for examples of the use of the -exec
option. The specified command is run once for each
matched file. The command is executed in the starting
directory. There are unavoidable security problems
surrounding use of the -exec action; you should use the
-execdir option instead."
If you want to just find the string in a file and you do not HAVE TO first find a directory and then a file and then search, you can just simply find the text with grep.
Go to the the parent directory and execute :
grep -iR "abcd"
Or from any place,
grep -iR "abcd" /var/log/mylogs/
Suggesting a grep command on find filter results:
grep "abcd" $(find . -type f)

Mass Find/Replace within files having specific filename under command line

I am looking for a quick command to search all .htaccess files for a specific IP address and change it to another IP address from the command line
something like
grep -rl '255.255.254.254' ./ | xargs sed -i 's/254/253/g'
I know the above example is a bad way to do it, just an example (and showing I did some searching to find a solution
Search: files with filename .htaccess (within 2 levels deep of current path?)
Find: 255.255.254.254
Replace with: 255.255.253.253
or, is this too much to ask of my server and I would be better off replacing them as I find them?
Try:
find . -type f -name '.htaccess' -execdir sed -i 's/255\.255\.254\.254/255.255.253.253/g' {} +
How it works:
find .
Start looking for files in the current directory.
-type f
Look only for regular files.
-name '.htaccess'
Look only for files named .htaccess.
-execdir sed -i 's/255\.255\.254\.254/255.255.253.253/g' {} +
For any such files found, run this sed command on them.
Because . is a wildcard and you likely want to match only literal periods, we escape them: \.
We use -execdir rather than the older -exec because it is more secure against race conditions.

launch several scripts located in subdirectories

Here is my problem. I have a directory that contains multiple sub-directories. In each sub-directory, there is at least one script sh.
I want to do a script that execute sequentially all this scripts.
I am pretty new to linux.
Thanks for your help,
find . -name "*.sh" -exec {} \;
This is a shell command which, beginning in the directory it's being run in (specified by .), finds file names that end in .sh and then executes those files (the found file is substituted in the {}). The backslash prevents the semicolon from being expanded by the shell (here, bash).
Try doing it using find and for:
for file in `find . -type f -name "*.sh"`; do sh $file; done
Use can also store it in array and do it:
array=($(find . -type f -name "*.sh"))
for file in ${array[#]};do sh $file; done
From the top directory, run the following command:
for f in `find . -type f -name \*.sh`; do $f; done
The find command will locate all .sh files. The output of the find command (a whitespace separated list of pathnames to the scripts) becomes the input to the for command. The for command processes each input, assigning each entry to the variable f. The "$f" executes each script.

Insert line into multi specified files

I want to insert a line into the start of multiple specified type files, which the files are located in current directory or the sub dir.
I know that using
find . -name "*.csv"
can help me to list the files I want to use for inserting.
and using
sed -i '1icolumn1,column2,column3' test.csv
can use to insert one line at the start of file,
but now I do NOT know how to pipe the filenames from "find" command to "sed" command.
Could anybody give me any suggestion?
Or is there any better solution to do this?
BTW, is it work to do this in one line command?
Try using xargs to pass output of find and command line arguments to next command, here sed
find . -type f -name '*.csv' -print0 | xargs -0 sed -i '1icolumn1,column2,column3'
Another option would be to use -exec option of find.
find . -type f -name '*.csv' -exec sed -i '1icolumn1,column2,column3' {} \;
Note : It has been observed that xargs is more efficient way and can handle multiple processes using -P option.
This way :
find . -type f -name "*.csv" -exec sed -i '1icolumn1,column2,column3' {} +
-exec do all the magic here. The relevant part of man find :
-exec command ;
Execute command; true if 0 status is returned. All following arguments
to find are taken to be arguments to the command until an argument consisting
of `;' is encountered. The string `{}' is replaced by the current file name
being processed everywhere it occurs in the arguments to the command, not just
in arguments where it is alone, as in some versions of find. Both of
these constructions might need to be escaped (with a `\') or quoted to protect
them from expansion by the shell. See the EXAMPLES section for examples of
the use of the -exec option. The specified command is run once for each
matched file. The command is executed in the starting directory. There
are unavoidable security problems surrounding use of the -exec action;
you should use the -execdir option instead

Shell command to find files in a directory pattern

With a shell command i need to list all files on my server in the following directory pattern:
/home/*/public_html/images/*.php
Theres a few an its taking a long time to do this manually. I really have no idea when it comes to these commands.
find /path/to/directory/. -path "*/match/this/path/*" -type f -name "*.php"
Shell Script:
find /home/*/public_html/images -iname "*php" -exec echo {} \;
You can then change the -exec command to do whatever actions you want to the returned files. In this case, we echo them, but you could easily perform other actions as well.
Let bash expand the files for you and use ls to list them:
ls /home/*/public_html/images/*.php
Example output:
/home/grant/public_html/images/bar.php
/home/grant/public_html/images/foo.php
/home/marcog/public_html/images/helloworld.php
Use the PHP glob function
glob('/home/*/public_html/images/*.php')
It will return an array of the matching path strings. You can also just use:
ls /home/*/public_html/images/*.php
or:
for i in /tmp/*/public_html/images/*.php;
do
some_command "$i"
done
from the shell.

Resources