I am looking to replace the line export KEY_COUNTRY="US" with the data read in the variable $COUNTRY in the file /etc/openvpn/easy-rsa/vars
In my previous builds which I used with CentOS6, i used the command replace which is bundled with mysql-server. But now that function is no longer available, i am looking for ideas on alternate command to replace the data.
Thanks in advance.
You can use sed, but keep in mind that it can fail if $COUNTRY contrains control characters.
sed -i 's/KEY_COUNTRY="US"/KEY_COUNTRY="'"$COUNTRY"'"/' file
Using Perl would be safer, as it doesn't interpret variable contents as part of the syntax:
perl -i -pe 's/KEY_COUNTRY="US"/KEY_COUNTRY="$ENV{COUNTRY}"/' -- file
$COUNTRY must be accessible in the perl process, i.e. you need to export it or assign to it
COUNTRY=$COUNTRY perl ...
Related
I have a file that I pass to a bash command that will create an output in a loop like so:
for file in /file/list/*
do
command
done
I wish to save the output that would have gone to standard out of each loop to a text file in my working directory. Currently I am trying this:
for file in /file/list/*
do
command | tee "$file_command output.txt"
done
What I expect to see are new files created in my current directory titled file1.txt_commandoutput.txt, file2.txt_commandoutput.txt, etc. The output of the command should be saved as a different file for each file. However I get only one file created and it's called ".txt" and can't be opened by any standard software on Mac. I am new to bash scripting, so help would be much appreciated!
Thanks.
Your problem comes from the variable name you're using:
"$file_command_output.txt" looks for a variable named file_command_output (the dot cannot be in the variable name, but the alphanumerical characters and the underscore all can).
What you're looking for is "${file}_command_output.txt" to make the variable name more explicit.
You have two issues in your script.
First, the wrong parameter/variable is expanded (file_command instead of file) because it's followed by a character that can be interpreted as part of the name (the underscore, _). To fix it, enclose the parameter name in braces, like this: ${file}_command (see Shell Parameter Expansion in bash manual).
Second, even with fixed variable name expansion, the file won't be created in your working directory, because the file holds an absolute pathname (/file/list/name). To fix it, you'll have to strip the directory from the pathname. You can do that with either basename command, or even better with a modified shell parameter expansion that will strip the longest matching prefix, like this: ${file##*/} (again, see Shell Parameter Expansion, section on ${parameter##word}).
All put together, your script now looks like:
#!/bin/bash
for file in /file/list/*
do
command | tee "${file##*/}_command output.txt"
done
Also, to just save the command output to a file, without printing it in terminal, you can use a simple redirection, instead of tee, like this: command > "${file##*/}_com...".
If you are not aware of xargs, try this:
$ ls
file
$ cat > file
one
two
three
$ while read this; do touch $this; done < ./file
$ ls
file one three two
I am trying to batch fix some .scc files using vim and need to pass a substitution sting to it.
I'm trying to use vim -E to pass this line ":s/\r/\r/g"
I've tried embedding individual characters as a variable within the quotes but the \r messing it up.
Any advice would be appreciated.
Guessing at what you really want to do as it doesn't sound like a one-off change. The following will remove all \rs.
NOTE it does an inplace edit - no need to redirect etc.
perl -i.bak -p -e 's/\r+//g' filename(s)...
If you want to replace it with a single \r do
perl -i.bak -p -e 's/\r+/\r/g' filename(s)...
Perl will keep a backup but so should you.
It's not using vim but then perhaps you shouldn't want to.
In Vim, you must use \n in the search part and \r in the replacement part. But replacing \n with \r sounds a lot like doing nothing to me.
Anyway, launching Vim just for a substitution is probably a bit too much. You could use sed:
$ sed -i.orig 's/foo/bar/' foo.txt
Read $ man sed for more info.
got it. ':s/\\r/\\r/g'
I just needed the right level of quotation. The issue as I touched on earlier is that we get files that include PC double line breaks presumable made on a mac and the PC's can't read them properly.
So using sed to s/\r/\r\n/g wasn't really working for some reason, and maybe I could explore it more. But I think passing these to vim will help. I must use vim to send :set format=dos to the file.
Thanks all.
I have one set of files with naming convention bond_7.LEU.CA.1.dat bond_10.VAL.CB.1.dat..... and have other set of files starting with the string distance rather than bond with the same extension i.e.,distance_7.LEU.CA.1.dat .... and i am trying to merge corresponding or subsequent lines of files using paste command in shell scripting
I am intending to do
paste bond_7.LEU.CA.1.dat distance_7.LEU.CA.1.dat > ../raj/angle_dist_7.LEU.CA.dat
I have tried to use for loop and stuck with replacing the string of the file name to access the appropriate file.
Thanks in advance,
Any help will be appreciated.
#!/bin/bash
for FILE in bond*
do
paste "$FILE" "${FILE/bond/distance}" > "../raj/${FILE/bond/angle_dist}"
done
Is that it?
ps. Such substitutions don't work in pure sh. You should to use bash or ksh or zsh or smth like that.
pps. To use it with sh replace "${FILE/bond/distance}" with
`echo $FILE | sed 's/bond/distance/'`
I have a number of files (more than a hundred) that I want to process using Vim. A sample of the files’ contents is as follows:
xyz.csv /home/user/mydocs/abc.txt
/home/user/waves/wav.wav , user_wav.wav
I want this to be replaced by:
xyz.csv /var/lib/mydir/abc.txt
/var/sounds/wav.wav , wav.wav
In each of the files, the changes I need to make are the same. My questions are:
Can I use Vim search and replace functionality by calling it from within a Bash script?
If so, how do I go about it?
P.S. I have searched StackOverflow for similar questions and found some answers using ex scripts, etc. I want to know how I can call an ex script from within a bash script.
While vim is quite powerful, this is not something I would normally use vim for. It can be done using a combination of common command line utilities instead.
I've assumed that the blank line in your example above is actually blank and does not contain spaces or any other whitespace characters. You can use the following to do what you want.
sed -e "s,/home/user/mydocs,/var/lib/mydir," -e "s,/home/user/waves,/var/sounds," -e "/^$/d" file1
You can use that command together with find and a for loop to do this for a bunch of files:
for file in `find . -maxdepth 1 -type f`
do
sed -e "s,/home/user/mydocs,/var/lib/mydir," -e "s,/home/user/waves,/var/sounds," -e "/^$/d" $file
done
In the for loop, the find command above limits the output to all files in the current directory (including dot files), assigning each line from the output of find to the file variable and then running the sed command posted earlier to transform the file the way you want it to be transformed.
This is how you'd invoke an ed script from bash:
ed filename <<END
/^$/d
%s|/home/user/mydocs|/var/lib/mydir|
%s|/home/user/waves|/var/sounds|
%s|, user_|, |
w
q
END
To answer with vim, you can do
vim -e 'bufdo!%s:\(xyz.csv \)/home/user/mydocs/\(abc.txt\n\)\n.*:\1/var/lib/mydir/\2/var/sounds/wav.wav , wav.wav:' -e 'xa' FILES
Note, I had assumed, that the second line is statically replaced, as it had looked like in the question.
If you don't like writing long lines in your script, you can create a file like:
s/FOO/BAR/
" several replacement and other commands
w " write the file
bd " if you want to
Then do:
vim -e "buffdo!source /your_scriptfile" -e "x" FILES
HTH
If all the editing consists in a series of substitutions, the most
idiomatic way of accomplishing it using Vim would be the following.
Open all the target files at once:
vim *.txt
Run the substitution commands on the loaded files:
:argdo %s#/home/user/mydocs#/var/lib/mydir#
:argdo %s#/home/user/waves#/var/sounds#
:argdo %s#, \zsuser_##
...
If changes are correctly made, save the files:
:wall
If the editing you want to automate could not be expressed only
in substitutions, record a macro and run it via the :normal
command:
:argdo norm!#z
(Here z is the name of the macro to be run.)
Lastly, if the editing should be performed from time to time and
needs to be stored in a script, try using the approach described
in the answer to a similar question.
Answer
While most vim users would be aware of the % motion command for executing inclusive commands on the whole document in the current buffer. Most modern versions of vim (ie 6.x+) support actions on regex searches for exclusive actions like so:
:/regex/substitute/match/replace/ # as vim command line
+"/reges/s/match/replace" # as bash cli parameter
This breaks down into vim doing the following,
search for regex and put the cursor at start of found point
call internal substitute function (see :help s or :help substitute) [ could be other commands ]
match string with regex for substitution
replace with new string value
Effectively it operates the same as the :global command.
Notes
Command after regex search can be any command, including '!"shell command"' filter commands.
Reference Help
:help global
:help substitute
:help filter
I'm using perl on windows and am trying to do a one liner using perl to substitute a placeholder in a file using a windows variable that contains a dollar sign. Does anyone know what the correct usage is to make it work with the dollar sign. I've tried various ways and can't seem to get it to work.
For example, I have a properties file that has a token in it (!MYPASSWORD!) that I'm trying to replace like:
somevalue="!MYPASSWORD!"
I have a batch file that looks up a variable say called NEWPASSWORD that contains the password $abc12345$ and I want to use perl substitution to replace the value like the following. Note I may not always know where the $ signs are so I cant escape them. For example another password may be abc$124$563:
echo %NEWPASSWORD% <-- this would contain $abc12345$
perl -p -i.bak -e "s/!MYPASSWORD!/%NEWPASSWORD%/g" a.properties
When its done I want a.properties to be :
somevalue="$abc12345$"
Thanks in advance
Use ' as regexp delimeter symbol. It will disable all variable substitution:
perl -p -i.bak -e "s'!MYPASSWORD!'%NEWPASSWORD%'g" a.properties
I presume you are getting password from user input. why not just do that in Perl without having to go through batch since you are already using Perl? Its easier. you can then use modules like Term::Inkey to mask password and stuff.
simply use escape before dollar, like that :
\$