replace a line in linux file containing special characters - linux

Here is an extract from a script showing the variables for the script
PathToPiconPNG="/var/OscamSrvidPicon/picon/19.2E/"
PathToOscamSrvid="/var/OscamSrvidPicon/picon/19.2E/oscam.srvid"
PathToPiconTPL="/var/OscamSrvidPicon/oscam_picons/"
PathToTmp="/tmp/"
I want to run this script numerous times replacing (for example) this line:
PathToPiconPNG="/var/OscamSrvidPicon/picon/19.2E/"
with this lines
PathToPiconPNG="/var/OscamSrvidPicon/picon/28.2E/"
I have tried using sed (I know this example is wrong but you might get what im trying to achieve)
sed 's/{PathToPiconPNG="/var/OscamSrvidPicon/picon/19.2E/"}/{PathToPiconPNG="/var/OscamSrvidPicon/picon/28.2E/"}/g' filename.txt > newfilenam.txt
If that is not possible, is there any way that I can set the variable externally from another script

sed -E 's/picon\/.+\//picon\/28.2E\//' filename.txt > newfilenam.txt

Related

bash: How to replace an entire line in a text file by a part of its content

I have a text file, called texto.txt in Documentos folder, with some values like the ones below:
cat ~/Documentos/texto.txt
65f8: Testado
a4a1: Testado 2
So I want to change a whole line by using a customized function which gets as parameters the new value.
The new value will always keep the first 6 characters, changing only what comes after them. Although I am testing only the first four.
Then I edited my .bashrc including my function like shown below.
muda()
{
export BUSCA="$(echo $* | cut -c 1-4)";
sed -i "/^$BUSCA/s/.*/$*/" ~/Documentos/texto.txt ;}
When I run the command below it works like a charm, but I feel it could be improved.
muda a4a1: Testado 3
Result:
cat ~/Documentos/texto.txt
65f8: Testado
a4a1: Testado 3
Is there a smarter way to do this? Maybe by getting rid of BUSCA variable?
I'd write:
muda() {
local new_line="$*"
local key=${newline:0:4}
sed -i "s/^${key//\//\\/}.*/${new_line//\//\\/}/" ~/Documentos/texto.txt
}
Notes:
using local variables, not exported environment variables
does not call out to cut, bash can extract a substring
escaping any slashes in the variable values so the sed code is not broken.

How to read a variable from file, modify and safe it to an other variale

What I want:
There is a file /scripts/backup/config.cfg which contains variables. In my specific case the important ones are:
BACKUPLOCATION=""
ROOTLOCATION="/backup"
Then there is a script /scripts/backup/performBackup.sh
For a specific reason I want a part of the script do the following operations:
read the value of the variable ROOTLOCATION
add a ("/" and) timestamp (Date&Time)
safe the new created value to BACKUPLOCATION (by replacing its current value)
Example
If this is the previous state of the config.cfg:
BACKUPLOCATION="dummy"
ROOTLOCATION="/backup"
After the script ran it should be:
BACKUPLOCATION="/backup/2020-05-02-23-00"
ROOTLOCATION="/backup/"
What I tried
First of all the config file gets "loaded" using
source /scripts/backup/config.cfg
I then tried to use the sed command but the quotes are messing with me. Here is one try (which didn't work):
sed -i 's/BACKUPLOCATION\=.*/BACKUPLOCATION="'$ROOTLOCATION/$(date +%Y-%m-%d-%H-%M)'"/' /scripts/backup/config.cfg
Try this:
source /scripts/backup/config.cfg
sed -i 's|BACKUPLOCATION=.*|BACKUPLOCATION="'"$ROOTLOCATION/$(date +%Y-%m-%d-%H-%M)"'"|' /scripts/backup/config.cfg
The problem with your sed is that you use / as delimiter, which is present in $ROOTLOCATION after expansion, therefore sed fails. I used |, which is usually is not present in filenames. If you ever create a file with |, that sed will fail too! So, "know your data" :)

sh shell redirecting a subshell to file, can't find the right syntax

i want to run a sed command with programatically with changing parameters.
the thing is that i cant find the correct syntax to do so.
i want to configure a conf file with this and
change a dir path to another.
i'm currently using:
RESULT=$("sed 's/--ROOT_DIR--/${root_inst_dir}/g' ${root_inst_dir}/${tool_name}/etc/${tool_name}.conf > ${SOURCE_DIR}/${tool_name}.conf")
and i get the error message:
./change_tst.sh: line 7: sed 's/--ROOT_DIR--//home/test_dir/g' /home/tst/conf.conf > /home/script_tst/conf.conf: No such file or directory
the ">" is not working for some reason.
what am i doing wrong? or what is the best way to do this ?
UPDATE
i drooped the result variable and now running this:
(sed 's/--ROOT_DIR--/$root_inst_dir/g' ${root_inst_dir}/${tool_name}/etc/${tool_name}.conf) > ${SOURCE_DIR}/${tool_name}.conf
the new file is being created in > ${SOURCE_DIR}/${tool_name}.conf,
but the search/replace is happening literally and not as a variable...
thanks.
Putting " inside parenthesis will result in bash wanting to execute a command named exactly:
sed 's/--ROOT_DIR--/${root_inst_dir}/g' ${root_inst_dir}/${tool_name}/etc/${tool_name}.conf > ${SOURCE_DIR}/${tool_name}.conf"
Such command does not exist on your system.
Probably you intended to put " outside $(...):
RESULT="$(sed 's/--ROOT_DIR--/${root_inst_dir}/g' ${root_inst_dir}/${tool_name}/etc/${tool_name}.conf > ${SOURCE_DIR}/${tool_name}.conf)"
Better way, if you don't need the RESULT variable and if you want to properly escape root_inst_dir variable:
sed 's#--ROOT_DIR--#'"${root_inst_dir}"'#g' "${root_inst_dir}/${tool_name}/etc/${tool_name}.conf" > "${SOURCE_DIR}/${tool_name}.conf"
Or if you need RESULT variable:
sed 's#--ROOT_DIR--#'"${root_inst_dir}"'#g' "${root_inst_dir}/${tool_name}/etc/${tool_name}.conf" > "${SOURCE_DIR}/${tool_name}.conf"
RESULT=$(cat ${SOURCE_DIR}/${tool_name}.conf)

how to edit a file to keep lines of same length only by using shell command

I have a file with contents like below.
7f22cebc9330
600e98
7fff1814ff50
7f22cebc95c0
7f22cebc95b8
4002a8
7f22cebc95bc
You can see that some have 12 characters (eg:7f22cebc9330 ), and some have six (eg: 600e98).
How can I edit this file such that only lines with 12 characters are kept in the file, removing all the lines that are NOT of 12 characters length ?
So that my new file would look like this:
7f22cebc9330
7fff1814ff50
7f22cebc95c0
7f22cebc95b8
7f22cebc95bc
I mean by using shell command in linux.
Thanks.
awk 'length() == 12' input.file > output.file
There are several tools that will allow you to edit the file directly (gnu sed, perl, etc), but doing so is a mistake. Write the output to a new file, and use the shell to rename if necessary.

How can I replace a specific line by line number in a text file?

I have a 2GB text file on my linux box that I'm trying to import into my database.
The problem I'm having is that the script that is processing this rdf file is choking on one line:
mismatched tag at line 25462599, column 2, byte 1455502679:
<link r:resource="http://www.epuron.de/"/>
<link r:resource="http://www.oekoworld.com/"/>
</Topic>
=^
I want to replace the </Topic> with </Line>. I can't do a search/replace on all lines but I do have the line number so I'm hoping theres some easy way to just replace that one line with the new text.
Any ideas/suggestions?
sed -i yourfile.xml -e '25462599s!</Topic>!</Line>!'
sed -i '25462599 s|</Topic>|</Line>|' nameoffile.txt
The tool for editing text files in Unix, is called ed (as opposed to sed, which as the name implies is a stream editor).
ed was once intended as an interactive editor, but it can also easily scripted. The way ed works, is that all commands take an address parameter. The way to address a specific line is just the line number, and the way to change the addressed line(s) is the s command, which takes the same regexp that sed would. So, to change the 42nd line, you would write something like 42s/old/new/.
Here's the entire command:
FILENAME=/path/to/whereever
LINENUMBER=25462599
ed -- "${FILENAME}" <<-HERE
${LINENUMBER}s!</Topic>!</Line>!
w
q
HERE
The advantage of this is that ed is standardized, while the -i flag to sed is a proprietary GNU extension that is not available on a lot of systems.
Use "head" to get the first 25462598 lines and use "tail" to get the remaining lines (starting at 25462601). Though... for a 2GB file this will likely take a while.
Also are you sure the problem is just with that line and not somewhere previous (ie. the error looks like an XML parse error which might mean the actual problem is someplace else).
My shell script:
#!/bin/bash
awk -v line=$1 -v new_content="$2" '{
if (NR == line) {
print new_content;
} else {
print $0;
}
}' $3
Arguments:
first: line number you want change
second: text you want instead original line contents
third: file name
This script prints output to stdout then you need to redirect. Example:
./script.sh 5 "New fifth line text!" file.txt
You can improve it, for example, by taking care that all your arguments has expected values.

Resources