How to uncomment multiple lines on second pattern match using sed? - sed

I am trying to use sed to uncomment a block of text in this config file.
The code I came up with uncomments 7 lines starting from and including the pattern match on the first match but I need it to only work on the second match and skip the first match.
sed '/#location.~.*$/,+6s/#/ /' default.conf
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
>

This might work for you (GNU sed):
sed 'x;/./{x;/#location/,+6s/#/ /;b};x;/#location/h' file
Use the hold space (HS) to store a flag and only act on the address range if the flag has been set.

I would say, using shell script to change your codes is risky. many special case could make it fail.
I would call it "text transformation" instead. it will remove the leading # from #location ~ \.php$ { line to first #} line.
awk onliner:
awk '/^#location ~/{s=1}s{if($0~/^#}/)s=0;sub("#"," ")}1' file
see example: (file is your content)
kent$ awk '/^#location ~/{s=1}s{if($0~/^#}/)s=0;sub("#"," ")}1' file
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
location ~ \.php$ {
proxy_pass http://127.0.0.1;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
I hope the output above is what you need.

With awk (this is more suitable & easier than sed for this task):
awk -F# '
/^#location/{l++}
l<2 {print}
l==2{print $2}
l==2 && $2 ~ "}" {l=0;next}
' file.txt

Related

sed command to swap elements in a line

I'm trying to swap a few elements in the apache dir.conf file which looks like this:
<IfModule mod_dir.c>
DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>
I want to swap, index.html for index.php, this is the desired output:
<IfModule mod_dir.c>
DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
</IfModule>
This is the command I have so far, but I am sure there is a much cleaner way to write it:
sed -e '2s/\(.*\)\s\(.*\)\s\(.*\)\s\(.*\)\s\(.*\)\s\(.*\)\s\(.*\)\s\(.*\)/\1 \2 \6 \3 \4 \5 \7 \8/'
btw I left the '2s...' since I only want to modify the second row of the file.
Perl to the rescue!
perl -pe 's/index\.(?:(php)|(html))/$1 ? "index.html" : "index.php"/ge if 2 == $.'
The /e makes the replacement part of the s/// operator act like code, so $1 is tested for truthfulness, and if it's true, then there was php, so we replace it with html, otherwise, there was html, so we replace it with php.

Unterminated Delimeter in sed Command While Passing a Variable

I've been struggling with this for more than an hour now and I'm not sure what's wrong. Using Perl, I'm trying to use sed to do an in-line replacement of a string in /etc/nginx/nginx.conf as noted by using the sed command below:
my $replacement_string = getstringforreplace();
my $command = qq ( sudo sed -i "s~default_type application/octet-stream;~default_type application/octet-stream;$replacement_string~" /etc/nginx/nginx.conf );
system ( $command );
die ( $command ); # Using this for debugging purposes.
I'm really trying to place the $replacement_string after matching that 'default type' line in nginx.conf but I'm not sure what to use besides sed.
I've (1) changed the delimiters to avoid any issues with the forward slashes, (2) double quoted the replacement (I'm really not sure why, I was using single quotes before), and (3) removed a newline character I had right before the $replacement_string, among other things.
I went ahead and put the die ( $command ); in there as noted in this answer, but I'm not seeing what's wrong. This is what that returns -- which is pretty much what I want:
sudo sed -i "s~default_type application/octet-stream;~default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
tserver_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
~" /etc/nginx/nginx.conf
The $replacement_string is returned by the call to the subroutine getstringforreplace() below:
sub getstringforreplace
{
my $message = qq (
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
tserver_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
);
return $message;
}
Any guidance would be really appreciated as I'm not sure how to get rid of this unterminated `s' command issue. I'm thinking now it has to do with that qq() from the subroutine I'm calling.
sed doesn't like newlines in the replacement literal.
$ sed 's~a~b~' /dev/null
$ sed 's~a~b
~' /dev/null
sed: -e expression #1, char 5: unterminated `s' command
It does accept \n, so you could replace the newlines with \n. Of course, you could simply do the work in Perl. This will help you address a number of other issues:
Shell command injection bug.
Lack of escaping \ in the replacement literal.
Lack of error detecting and handling.
Thanks to #Beta's comments above I was able to obtain the result I wanted. It involved:
changing the subroutine getstringforreplace() to print the contents of qq() to a temporary file,
doing an in-place replacement using sed to read the contents of that file into /etc/nginx/nginx.conf,
and then removing the temporary file.
...which is below:
getstringforreplace(); # Prints $replacement_string to temp.txt.
my $command = qq ( sudo sed -i -e '/octet-stream;/r temp.txt' /etc/nginx/nginx.conf );
system ( $command );
system ( 'sudo rm temp.txt' );
Ideally, I would have liked to not have to print to a file, etc., but for the moment this yields the desired result.

Yii2 cannot reach the backend part

I really don't get it how can i get to that backend .. How i installed the advanced template is like the way they show it in the official site : http://www.yiiframework.com/download/ . Everything step by step. When i try frontend.dev (in my case eshop) i am redirected to the front end part but when i try backend.dev(in my case eshop/admin) i am also redirected to the frontend.
This is my host file:
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
# 127.0.0.1 modules
127.0.0.1 eshop
127.0.0.1 eshop/admin
0.0.0.1 mssplus.mcafee.com
And the vhost.conf:
<VirtualHost *:80>
ServerName eshop
DocumentRoot "C:/xampp/htdocs/eshop/frontend/web/"
<Directory "C:/xampp/htdocs/eshop/frontend/web/">
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
# use index.php as index file
DirectoryIndex index.php
# ...other settings...
# Apache 2.4
Require all granted
## Apache 2.2
# Order allow,deny
# Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName eshop/admin
DocumentRoot "C:/xampp/htdocs/eshop/backend/web/"
<Directory "C:/xampp/htdocs/eshop/backend/web/">
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
# use index.php as index file
DirectoryIndex index.php
# ...other settings...
# Apache 2.4
Require all granted
## Apache 2.2
# Order allow,deny
# Allow from all
</Directory>
</VirtualHost>
Where is my mistake ? A lot of thanks in advance!
Using a slash (/) in hostname is illegal, as it is defined in RFC 952. Therefore in the URL "http://eshop/admin" the server name is "eshop" and apache is using of course your first virtual server setting.
Summarized, your idea will never work. You should use eshop-admin as server name.

Redirecting nginx to index.php

I have nginx on a Raspberry Pi. In /etc/nginx/sites-available/default, I replaced server{} with the following, and I can access /var/www/html/index.php using http://192.168.1.210/.
server {
listen 80;
server_name $domain_name;
root /var/www/html/;
index index.html index.htm;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location ~\.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
try_files $uri =404;
include fastcgi_params;
# if (!-e $request_filename){ rewrite ^(.*)$ /index.php break; }
}
}
I now wish to add some simple redirecting similar to Apache's
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
I added if (!-e $request_filename){ rewrite ^(.*)$ /index.php break; at the end (see the above commented out line) and placed http://192.168.1.210/page2 in the browser, however, the script still doesn't redirect to /var/www/html/index.php
How can I redirect any non-existing requests to index.php?
What you are trying to accomplish is to redirect files and directories that do not exist towards index.php?
This can be done by using:
try_files $uri $uri/ /index.php;
Or which makes more sense:
error_page 404 /index.php;
This will also redirect missing files, images, ...

How do I use sed to insert a line into a configuration file?

What's the best way to use sed to insert:
include /etc/nginx/sites-directives/*.conf;
into a file, /etc/nginx/sites-available/VIRTUALSERVER_DOM
on a line right after:
fastcgi_read_timeout 60;
sed -i '/fastcgi_read_timeout 60;/ a\
include /etc/nginx/sites-directives/*.conf;' /etc/nginx/sites-available/VIRTUALSERVER_DOM
Explain: when reach fastcgi_read_timeout 60;, add a line (after) include /etc/nginx/sites-directives/*.conf;