How to test linux variable within sed file? - linux

I have a sed file that contains contains a few substitutions, it is executed on a file using the following syntax:
sed -f mysedfile file.txt > fixed_file.txt
I would like to test a system variable and depending what that variable contains, execute different sed operations on file.txt.
Would it be possible to put this logic into mysedfile?
Thank you for the help.

Perl was explicitly created to get around limitations of sed and awk. The -p mode runs a script for each line in the file. You can put it on the commandline:
perl -p -e "s/foo/\$ENV{'HOME'}/e" < files.txt
Or move the script to a file (you can remove the '\' before the $)
perl -p file.pl < files.txt
Or make the first line of your script like this so you can run it directly.
#!/usr/bin/perl -p

Related

How to source a variable from script into shell without executing the script

I have the below bash script:
FILES="file_1 file_2 \
file_3"
export FILES
run_test
It has a FILES variable that is written on multiple lines and then the script calls another script.
I want to source the script to have the variable FILES defined in the shell but without calling the other script "run_test"
I tried to grep the FILES variable from script but it gets the first line only in the variable.
Any recommendations please?
You might want the consider an env.sourceme file with shared settings like FILES=.
This file can be sourced by both your original and your new script.
When you don't want/can change the original file, you need to do something else.
When your sed supports -z you can use
source <(sed -rz 's/.*(FILES="[^"]*").*/\1/' inputscript)
You can use grep when you parse the inputscript first:
source <(tr "\n" "\r" < inputscript | grep -Eo 'FILES="[^"]*"' | tr "\r" "\n")

perl -p -i -e inside a shell script

#!/usr/bin/env bash
DOCUMENT_ROOT=/var/www/html/
rm index.php
cd modules/mymodules/
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' `grep -ril y.yy.yy.y *`
shows shows a warning
-i used with no filenames on the command line, reading from STDIN.
It prevents running rest of the scripts.
Any solutions ?
Actually I need to run
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' `grep -ril y.yy.yy.y *`
Inside a shell script
I am using ubuntu with docker.
Let's look at this a step at a time. First, you're running this grep command:
grep -ril y.yy.yy.y *
This recursively searches all files and directories in your current directory. It looks for files containing the string "y.yy.yy.yy" in any case and returns a list of the files which contain this text.
This command will return either a list of filenames or nothing.
Whatever is returned from that grep command is then passed as arguments to your Perl command:
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' [list of filenames]
If grep returns a list of files, then the -p option here means that each line in every file in the list is (in turn) run through that substitution and then printed to a new file. The -i means there's one new file for each old file and the new files are given the same names as the old files (the old files are deleted once the command has run).
So far so good. But what happens if the grep doesn't return any filenames? In that case, your Perl command doesn't get any filenames and that would trigger the error that you are seeing.
So my (second) guess is that your grep command isn't doing what you want it to and is returning an empty list of filenames. Try running the grep command on its own and see what you get.

Running shell script that replace content in texfile

What I want to achieve is that I replace some placeholder inside all *.txt files of one folder.
I don't really often use shell scripts, but for this purpose I want to use it. My first try was this:
#!/bin/sh
MYSTRING="Thesedentary"
echo $MYSTRING
perl -pi -w -e 's/{{PLACEHOLDER}}/${MYSTRING}/g;' /path_to_directory/*.txt
I know that perl -pi -w -e 's/.../.../g;' /path_to_directory/*.txt will replace the content of the first /.../ with the second /.../ but as you can see I want to replace the second /.../ with the content of an variable -> MYSTRING. All I get is this:
Name "main::MYSTRING" used only once: possible typo at -e line 1.
But the {{PLACEHOLDER}} in the files will be replaced with nothing ->
Thanks
Found a solution:
#!/bin/sh
MYSTRING='Thesedentary'
eval "perl -pi -w -e 's/{{TEST}}/${MYSTRING}/g;' /path_to_directory/*.js"
use eval to execute the command.

Paste a chunk of text from stdin to a specific location in a file

I'm trying to figure out how to efficiently copy-paste from X application to the terminal. Specifically I want to highlight a text section in my web browser, then paste this commented to a file after the shebang line.
the code I have so far is this:
xclip -o | sed 's/^/#/' | sed '2n' myscript.pl
the first command takes the text that I have highlighted in my browser
the second command comments the lines by adding #
the last bit does not work..
what I am trying to do here is append the text after line number 2 to my script. But obviously I am doing this wrong.. Does anyone have a helpful suggestion?
You can use sed read for safely handling all types of input, including input with special characters and multiple lines. This requires an intermediate file:
xclip -o | sed -e 's/^/#/g' -e '$s/$/\n/' > TMP && sed -i '1r TMP' den && rm TMP
sed only operates on one input stream (either a pipe or a file), if you are using the output of xclip as the data stream then you can't also tell sed to read from a file. Instead you could use command substitution to store the modified output, and use that in a separate command. How about:
sed "2i$(xclip -o | sed 's/^/#/')" myscript.pl
This will print the amended file to stdout, if you want to edit the file itself then use the -i flag.

How to search and replace text in a file from a shell script?

I'm trying to write a shell script that does a search and replace inside a configuration file upon start-up.
The string we're trying to replace is:
include /etc/nginx/https.include;
and we want to replace it with a commented version:
#include /etc/nginx/https.include;
The file that contains the string that we want to replace is:
/etc/nginx/app-servers.include
I'm not a Linux guru and can't seem to find the command to do this.
perl -p -i -e 's%^(include /etc/nginx/https.include;)$%#$1%' /etc/nginx/ap-servers.include
If the line might not end in the ;, use instead:
perl -p -i -e 's%^(include /etc/nginx/https.include;.*)$%#$1%' /etc/nginx/ap-servers.include
If you want to preserve the original file, add a backup extension after -i:
perl -p -i.bak -e 's%^(include /etc/nginx/https.include;)$%#$1%' /etc/nginx/ap-servers.include
Now, explaining. The -p flag means replace in-place. All lines of the file will be fed to the expression, and the result will be used as replacement. The -i flag indicates the extension of the backup file. By using it without anything, you prevent generation of backups. The -e tells Perl to get the following parameter as an expression to be executed.
Now, the expression is s%something%other%. I use % instead of the more traditional / to avoid having to escape the slashes of the path. I use parenthesis in the expression and $1 in the substituted expression for safety -- if you change one, the other will follow. Thus, %#$1% is actually the second % of s, followed by the desired #, $1 indicating the pattern inside parenthesis, and the last % of s.
HTH. HAND.
sed -i 's/foo/bar/g' config.txt
This replaces all instances of foo (case insensitive) with bar in the file config.txt
Check out sed:
sed -i -r 's|^(include /etc/nginx/https.include;)$|#\1|' /etc/nginx/app-servers.include
-i means do the substitution in-place and -r means to use extended regular expressions.
cd pathname
for y in `ls *`;
do sed "s/ABCD/DCBA/g" $y > temp; mv temp $y;
done
This script shold replace string ABCD to DCBA in all the files in pathname

Resources