Shell script to replace all occurrnces of string with a value - linux

I'm new to shell script.
I have a YAML file that consists of placeholder . I need to replace all the occurrences of placeholder <test-name> with a value sweta
script.sh
Name="sweta"
Below is the example of YAML file
metadata:
name: <test-name>-svc
namespace: abc
spec:
selector:
app: <test-name>
ports:
- protocol: TCP
name: http
port: 80
targetPort: 8080
My expected output is:
metadata:
name: sweta-svc
namespace: abc
spec:
selector:
app: sweta
ports:
- protocol: TCP
name: http
port: 80
targetPort: 8080
Can someone help me?
Appreciate all your help. Thanks in advance!

There are two easy ways to accomplish your search and replace <test-name> string with sweta
Note: Assuming your yaml file name is config.yaml
Option-1: Using stream editor command 'sed' as below:
To overwrite the original file
sed -i 's/<test-name>/sweta/g' config.yaml
To write the output to a different file
sed 's/<test-name>/sweta/g' config.yaml > updated_config.yaml
The syntax of sed command is sed -i 's/original/new/g' file.txt
where
sed is the command name
-i stands for in-place edit. This option is used to overwrite the original file. If you don't use this, you have to redirect output to a different file as done in second command above.
s stands for substitute
original is the search string
new is the replace string
g is for global (replace all occurrences). Omitting this will just replace only the first occurence
file.txt is the text file (Linux doesn't use extensions like .txt but people often name files with such extensions as a convention to denote file type)
Option-2: Use 'awk' command:
awk is a very powerful text processing command with its own language syntax, but this search and replace is quite easy:
awk '{gsub("<test-name>", "sweta"); print $0}' config.yaml > updated_config.yaml

Related

how to comment an idented line in a file

I am trying to comment a line within a .yml file through the command line, I am using this command sudo sed -i '/<pattern_to_find>/s/^#//g' /etc/metricbeat/metricbeat.yml an it works fine as long as the line is not idented, but I am loking to change an idented line such as:
setup.kibana:
# Kibana Host
# Scheme and port can be left out and will be set to the default (http and 5601)
# In case you specify and additional path, the scheme is required: http://localhost:5601/path
# IPv6 addresses should always be defined as: https://[2001:db8::1]:5601
# host: "localhost:5601"
# Kibana Space ID
any ideas how to achieve this? I cannot figure it out
Although I strongly encourage you not use the -i option to sed, I will not discuss that beyond mentioning it here. You just need to change your search pattern. Try:
sed -E '/^( *)#( host: "localhost:560!")/s//\1 \2/'
This will fail to match hard tabs. Depending on how much portability you want between different versions of said, that can be a pain to deal with. But the following should work:
sed -E '/^([[:space:]]*)#( host: "localhost:560!")/s//\1 \2/'

update file content with placehodler

I’ve the following yaml file, in which I want to substitute %IMG_NAME% with a shell variable which I have already defined, e.g. $IMG_NAME.
This is the input file
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 1
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: %IMG_NAME%. //this the value to update
imagePullPolicy: Always
ports:
- containerPort: 5000
resources:
limits:
memory: 50Mi
requests:
memory: 25Mi
I try to do the following which doesn’t work, any idea ?
sed -e ’s,myimage,’$IMG_NAME',g' < deployment.yaml
I have no clue why you write update-dep: in your attemp. What is that?
Anyway, maybe you just want to do this:
sed 's/%IMG_NAME%/'"$IMG_NAME"'/g' deployment.yaml
where
double quoting $IMG_NAME is just a good habit,
-e is not necessary,
using , instead of / is unnecessary too, as pointed out on a comment
Not specific to sed, it is very important to know the following:
the symbol ' is a single quote, not the right single quotation mark that you put in your question (’).
if you have an actual file you want to pass to a unix program (e.g. sed, awk, and many others) you don't need to pass it like this, program < file, becuase many of these programs accept a file name as a command line argument, so you can do program file. Doing so, the program is aware of the file name (it isn't when you do program < file) and it is also aware it is a file in the first place (after < you could put something which is not a file). If the program is not aware it's working on a file (or it's not aware of what the filename is), options like sed's -i option cannot be used, because the program has no clue where it should overwrite.

print string before pattern match for a non standard file

I have requirement were, whenever the script matches 'host2', I would like it to print the module name (text within square braces) under which the 'host2' is listed. I know grep -B would get text before the string match but my file is does not follow a standard pattern.In this case How to get text in braces which is before the string match?
[network]
host1
host2
[webserver]
host1
host9
host7
host5
host6
host2
[db]
host11
host19
Output would be :
network
webserver
You can use this awk command:
awk '/^\[.*\]/{gsub(/[][]/, ""); m=$0} $1=="host2"{print m}' file
network
webserver
How about this:
[\[a-zA-Z]+]((?=[\n\w]+host2))
awk '{gsub(/[\[\]]/,"")}$1~/network|webserver/' file
network
webserver

Find and Replace value using SED

I have one file which contains key value pair
properties.env
development_port=8080
development_type=tcp
staging_port=8081
development_type=http
I need to read value from properties.env and replace it in another file based on some environment variable value lets say ENVIRONMENT=staging/development
config.yml
server:
adminConnectors:
-
port: 18001
type: http
The final output of config.yml should be if ENVIRONMENT=staging
server:
adminConnectors:
-
port: 8081
type: http
How can i achieve this using sed command?
Since the properties file looks like it has the right syntax you could just source it, and then replace the entire port line:
source properties.env
sed --in-place "s/port.*/port: $staging_port/" config.yml
This, of course, assumes the "port" line appears only once in your config.

How to replace Windows-style CR/LF line endings with Linux-style endings in ansible?

I tried this in my task, but doesn't seem to work
- name: Fix line endings from CRLF to LF
local_action: replace dest={{my_dir}}/conf/{{item}} regexp='\r\n' replace='\n'
I usually do this using sed as follows and it works
sed -i 's/\r//g' file
I want to avoid using shell module to do this replacement as it throws a warning in ansible
You can remove the CRLF line endings with the -replace command. Your playbook might look like:
---
- hosts: all
tasks:
- local_action: replace dest={{my_dir}}/conf/{{item}} regexp="\r"
By not specifying the replace parameter in the - replace command, it will just remove all carriage returns. See http://docs.ansible.com/ansible/replace_module.html.
I tested this with a local file I created and it worked when testing on localhost. It also worked when I added localhost to the /etc/ansible/hosts file and had the following playbook instead:
---
- hosts: all
tasks:
- replace: dest={{my_dir}}/conf/{{item}} regexp="\r"
Just be sure to use the absolute filepath.
You can do something like this:
set_fact:
my_content: "{{ lookup('file', "{{my_dir}}/conf/{{item}}" ) | replace('\r\n', '\n')}}"
After this you can use the content or save in the disk.
The following converts line endings using the Jinja2 template engine. A line-ending directive is inserted at the beginning of the source file on the ansible machine (delegate_to: localhost). Sending the file to the downstream server can then be done by applying template or win_template to the file.
It handles source files with any line-ending, which could be useful if you're working through a list of files from more than one origin.
- name: prepare to add line endings
lineinfile:
insertbefore: BOF
dest: '{{ src_file }}'
line: '#jinja2: newline_sequence:"\n"'
#for Linux to Windows: #line: '#jinja2: newline_sequence:"\r\n"'
delegate_to: localhost
- name: copy changed file with correct line-endings
template: # win_template for Linux to Windows
src: '{{ src_file }}'
dest: '{{ dest_file }}'

Resources