I'm trying to replace the following string in a wordpress sql file:
http:\\/\\/firstdomain.com\\/qwerty\\/wp-content\\/uploads\\/2018\\/07\\/section-shape.png
to
https:\\/\\/seconddomain.com\\/wp-content\\/uploads\\/2019\\/06\\/section-shape.png
I tried the following command which obviously didn't work
sed -i "s#'http:\\/\\/firstdomain.com\\/qwerty\\/wp-content\\/uploads\\/2018\\/07\\/section-shape.png'#'https:\\/\\/seconddomain.com\\/wp-content\\/uploads\\/2019\\/06\\/section-shape.png'#g" database.sql
Someone please help to understand where I missed. Thank you very much.
You can't seriously apply a sed to a .db file because... well, it's database file not text (most likely sqlite by the way).
Instead, you should perform the string replacement with an (UPDATE) SQL query from the SQLite console (or whatever SQL client you have). Check this link for the replace method in SQLite for example.
Your first mistake is enclosing your script in double quotes instead of single, thereby inviting the shell to parse its contents before sed gets to see it and thus eating up one layer of backslashes.
If you have to deal with single quotes (which you shouldn't given your posted sample input but anyway...) never do this:
sed "s/foo'bar/stuff/"
do this instead:
sed 's/foo'\''bar/stuff/'
so the shell isn't interpreting every part of your script.
Beyond that - sed doesn't understand literal strings (see Is it possible to escape regex metacharacters reliably with sed), so instead just use a tool that does, e.g. awk:
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]="" }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+length(old)) }
1' \
'http:\\/\\/firstdomain.com\\/qwerty\\/wp-content\\/uploads\\/2018\\/07\\/section-shape.png' \
'https:\\/\\/seconddomain.com\\/wp-content\\/uploads\\/2019\\/06\\/section-shape.png' \
file
https:\\/\\/seconddomain.com\\/wp-content\\/uploads\\/2019\\/06\\/section-shape.png
Related
I generate password from php (thru web page) using shell_exec / dd/ /dev/urandom.
I want to eliminate
"/\
characters from my generated password.
If I do a replacement in my sed line with
's/["/\]/!/g'
the script fails to execute. However I tested this from command line like
echo "this /is \"a \test" | sed -e 's/["/\]/!/g'
Then I get the right result : this !is !a !test
If I eliminate this replacement section from my sed line, php script does execute properly. What seems to be the issue? I thought characters within brackets [] is safe and does not need escaping.. is that the issue?
In PHP, if you use the command in a double quoted string literal, you need to escape the " with a single backslash, \", and the backslash inside the bracket expression must also be escaped.
In the end, this must look like
sed 's/[\"/\\]/!/g'
I have about 200 php files that containing some iconv() functions,
something like this:
iconv('GB2312','UTF-8',$aRow[$aColumns[3]])
iconv('GB2312','UTF-8',$rs1['supplier']);
iconv('GB2312','UTF-8',$aRow[ $aColumns[$i] ]);
i don't know what could be the best way to remove iconv('GB2312','UTF-8', and final ) in batch mode without touching the variable.
this RegEx could match my case but i don't know how to use it with sed:
^(iconv\(\'GB2312\'\,\'UTF-8\'\,)+|(\))
And i am also not sure that sed is the right solution in this case
Anyone faced a similar problem before?
You can use this sed command:
sed -i "s/iconv('GB2312','UTF-8',\([^)]*\))\(.*\)/\1\2/" file
which will extract your php variable into \1. /2 is the remaining of the line (a ; in the example you posted)
Try this cut statement with the output.
cat file|cut -d, -f3|tr -d ');'
This might work for you (GNU sed):
sed 's/iconv('\''GB2312'\'','\''UTF-8'\'',\([^)]*\))/\1/g' file
Use an example string as a template, replacing ' by '\'' and the variable to be kept as any characters from after the second , which is not a closing ). This variable is enclosed in quoted (...) i.e. \(...\) which may be transfered to the RHS of the substitution command as a back reference.
Try this sed:
cat file | sed 's/iconv(.*,.*,\(.*\)).*/\1/g'
This will extract only the variable.
With grep
grep -o '$[^)]*' infile
I have many fields in my smarty template files like this.
{$email} (this can be anything like -- {$description}, {$variable_name}
I want to replace it with {$email|escape:htmlall} or {$variable_name}
how can i do that in linux? I'm having difficulty writing regex in sed.
Try:
sed 's/{\(\$[^}\|]*\)}/{\1|escape:htmlall}/g'
As a test, use:
echo 'blabla {$email} blieblie {$name} bloebloe ${alreadydone|escape:htmlall}'|sed 's/{\(\$[^}\|]*\)}/{\1|escape:htmlall}/gi'
Things that this regexp does:
It replaces any string like {$} by {$|escape:htmlall}
It also makes sure that two consecutive fields (as in the example) are handled separately. This is done by demanding that in the no '}' may occur (this is done by the [^}\|]* part, which means: a series of zero or more characters which all may be anything but '}' and '|' (see below).
It ignores any tags that already were escaped (by ignoring any tag having a | within the curly braces).
Make a backup before and try this:
grep -rl "{$email}" yourdirectory | xargs sed -i 's/\{\$email\}/{$email|escape:htmlall}/g'
perl -ape 's/({\$\w+)(?!\|escape:htmlall)}/$1|escape:htmlall}/g' file
This is using the negative lookahead feature.
This will ignore variables that already have escape:htmlall.
I've been having trouble running a command using PHP's exec() function on Windows. Per a comment on PHP's site on exec():
In Windows, exec() issues an internal call to "cmd /c your_command".
My command looks like:
"path\to\program.exe" -flag1 attribute1 -flag2 attribute2 -flag3 "attribute3 attribute4"
Under regular execution of this command in my local command prompt, without the /c flag, the command runs fine. However, with the introduction of the /c flag, command prompt tells me that "The system cannot find the path specified."
I think the command prompt is interpreting the double-quoted argument as a path to another file, but that's the furthest I've gotten with this problem.
Does anybody have any ideas on how to get past this? Thanks!
I also encountered this issue, and the cause of it is, indeed, the internal use of "cmd /c" as described in your own answer.
I have done some investigation, and have found that this was resolved in PHP 5.3, which is why some commenters were unable to reproduce it.
It was fixed in the following commit:
https://github.com/php/php-src/commit/19322fc782af429938da8d3b421c0807cf1b848a#diff-15f2d3ef68f383a87cce668765721041R221
For anyone who still needs to support PHP 5.2, it is fairly easy to replicate the fix in your own code. Instead of:
$cmd = "...any shell command, maybe with multiple quotes...";
exec($cmd);
use
function safe_exec($cmd, &$output = null, &$result_code = null) {
if (strtoupper(substr(php_uname('s'), 0, 3)) == "WIN"
&& version_compare(PHP_VERSION, "5.3", "<"))
{
$cmd = '"' . $cmd . '"';
}
return exec($cmd, $output, $result_code);
}
$cmd = "...any shell command, maybe with multiple quotes...";
safe_exec($cmd);
This replicates the behaviour of PHP 5.3 and above, in the same way as in the above-linked commit.
Note that this applies to all shell commands, not just exec() as used in my example.
I've figured out the answer by myself...
After perusing cmd.exe's /? and trying to decipher that, I've noticed one important section:
If all of the following conditions are met, then quote characters on the command line are preserved:
No /S switch (Strip quotes)
Exactly two quote characters
No special characters between the two quote characters, where special is one of: & < >( ) # ^ |
There are one or more whitespace characters between the the two quote characters
The string between the two quote characters is the name of an executable file.
Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character. To negate this behaviour use a double set of quotes "" at the start and end of the command line.
It seems as though if there more than one pair of quotes at any time, quotation marks will be stripped from the second pair of quotes and on.
A relevant question: How do I deal with quote characters when using cmd.exe but not completely relevant, since PHP will not allow you to modify its exec() command by putting an /S flag on its call (which would definitely be a lot easier).
I've managed to work around this problem by directly changing directories with chdir() to the folder where the .exe is located, then chdir()'ing back to my original working directory. It's an extremely hacky solution, given the case that I'm lucky that I only have one set of arguments using double quotes. If anybody were to have multiple arguments using double quotes, I wouldn't know how to solve that...
Just a guess (I am not familiar with PHP on windows): maybe escape the quotes as " becoming ""?
"path\to\program.exe" -flag1 attribute1 -flag2 attribute2 -flag3 ""attribute3 attribute4""
Whatever the solution is, make sure that when there's some form of user-input that gets passed to this command as arguments that you use escapeshellarg and/or escapeshellcmd.
I hope it will help
escapeshellarg() — Escape a string to be used as a shell argument
escapeshellcmd() — Escape shell metacharacters
I am trying to run sed to do a multiline search and replace with the following string
$test = "sed -n '1h;1!H;${;g;s/iname=\"".$name.".*item>/".trim(xml)."/g;p;}' ".$file;
exec($test,$cmdresult);
sed is choice since the string to be searched is over 10 mb.
During execution compiler issues a warning
PHP Parse error: syntax error, unexpected ';'
How do I go about solving this?
You need to escape the $ in ${}.
$test = "sed -n '1h;1!H;\${;g;s/iname=\"".$name.".*item>/".trim(xml)."/g;p;}' ".$file;
exec($test,$cmdresult);
In order to let humans read your code, though, you should really split the string up. Create it by concatenating other strings, sprintf or HEREDOC.
Probably the $ sign inside the $test variable makes PHP think that there is another variable that should be expanded.
Try escaping the $ character (\$), and have a look at the relevant PHP strings doc.