How to prevent sed from changing linebreaks? - sh

I am changing content of a .js file with a .sh file but there's an unwanted side-effect.
.sh file:
# update file
version="0.1"
file="Test.js"
updated_line="const version = \"$version\";"
sed -i "1s/.*/$updated_line/" $file
Test.js file:
const version = "0";
const moreVars = {};
After running the .sh file the update seems to be successfull but my IDE is complaining that the linebreaks changed from CRLF to LF:
How can I make these changes while leaving the linebreaks the way they were?

sed is not linebreak aware, in that sense, CR character is just that CR character. If you want your line to have CR character, you have to add CR character. For sed it's just a character like any other.
updated_line="const version = \"$version\";"$'\r'
How can I make these changes while leaving the linebreaks the way they were?
Write a regex that matches CR character on the end of the line if it exists and preserve it.
s/.*\(\x0d\?\)$/$updated_line\1/

Related

Using Perl with Sed and Capture Groups to add another string to end of a string

I have a requirement to go through each file and add a new string at the end of a particular statement in the file. I already have the list of each such file (actually each file is a SAS code) having this statement . My aim is to edit each file in-place after creating a backup first.So i have decided to use PERL to do this in-place editing on a AIX 7.1 machine.
The particular statement that i intend to add to in each file will always have 3 keywords :FILENAME, FTP and HOST identifying such a statement and it is always terminated by a semicolon. The statement can also occur multiple times in same file.
Example of the statement in the file is:
FILENAME IN FTP "" LS HOST=XXXX USER=XXXX PASS=XXXX ;
The same type of statement also be in multiple lines as well with some additional options on the statement.
FILENAME Test FTP "Sample.xls"
CD="ABCDEFG"
USER=XXXXX
PASS=XXXXX
HOST=XXXXX
BINARY
;
OR
filename Novell ftp &pitalist.
HOST=&HOST.
USER="XXXXXXXX"
PASS="XXXXXXX"
DEBUG
LRECL=10000;
My aim is add a new string : %ftps_opts at the end of the above string just before ending semicolon.There should be atleast one space or a newline between existing statement and this new string as shown below.
FILENAME IN FTP "" LS HOST=XXXX USER=XXXX PASS=XXXX %ftps_opts;
FILENAME Test FTP "Sample.xls"
CD="ABCDEFG"
USER=XXXXX
PASS=XXXXX
HOST=XXXXX
BINARY
%ftps_opts;
filename Novell ftp &pitalist.
HOST=&HOST.
USER="XXXXXXXX"
PASS="XXXXXXX"
DEBUG
LRECL=10000 %ftps_opts;
Is there a way to use Capture group and PERL to capture the existing statement in each file just before the semicolon and then append the new string at the end of it with a space or newline? The Input.txt files has list of files having the FILENAME FTP statement as shown above.
Something like this :
#!/bin/bash
input="~/Input.txt"
while IFS= read -r line
do
echo "$line"
perl -p -i.orig -e 's/(capture group)/\1 %ftps_opts /gi' "$line"
echo "done"
done < "$input"
Thank you.
You can tell Perl to process the whole file instead of processing it line by line:
perl -0777 -pe 's/(filename[^;]*ftp[^;]*host[^;]*)/$1 %ftps_opts/gi' -- file

Remove a specific word from a file using shell script

I would request some help with a basic shell script that should do the following job.
File a particular word from a given file (file path is always constant)
Backup the file
Delete the specific word or replace the word with ;
Save the file changes
Example
File Name - abc.cfg
Contains the following lines
network;private;Temp;Windows;System32
I've used the following SED command for the operation
sed -i -e "/Temp;/d" abc.cfg
The output is not as expected. The complete line is removed instead of just the word Temp;
Any help would be appreciated. Thank you
sed matches against lines, and /d is the delete directive, which is why you get a deleted line. Instead, use substitution to replace the offending word with nothing:
sed 's/Temp;//g' abc.cfg
The /g modifier means "globlal", in case the offending word appears more than once. I would hold off on the -i (inline) flag until you are sure of your command, in general, or use -i .backup.
Thank you. I used your suggestion but couldn't get through. I appreciate the input though.
I was able to achieve this using the following SED syntax
sed -e "s/Temp//g" -i.backup abc.cfg
I wanted to take the backup before the change & hence -i was helpful.

Change Line Feeds from CRLF to LF in Eclipse

I recently noticed that the line-feeds of files in my project are CRLF but I want them as LF.(I get the following message from GIT GUI :
"UTF-8 Unicode text, with CRLF line terminators"
How can I solve this problem?
Try this :
Window->Preferences->General->Workspace: New Text file line delimiter
Just try below process
File--> Convert Line Delimiters to --> Unix

Replace specials characters with sed

I am trying to use a sed command to replace specials characters in my file.
The characters are %> to replace by ].
I'am using sed -r s/\%>\/\]\/g but i have this error bash: /]/g: No such file or directory, looks like sed doesn't like it.
Put your sed code inside quotes and also add the file-path you want to work with and finally don't escape the sed delimiters.
$ echo '%>' | sed 's/%>/]/g'
]
ie,
sed 's/%>/]/g' file
To complement Avinash Raj's correct and helpful answer:
Since you were using an overall unquoted string (neither single- nor double-quoted), you were on the right track by \-escaping individual characters in your sed command.
However, you neglected to \-quote >, which is what caused your problem:
> is one of the shell's so-called metacharacters
Metacharacters have special meaning and separate words
Thus, s/\%>\/\]\/g is mistakenly split into 2 arguments by >:
s/\% is passed to sed - as s/%, because the shell removes the \ instances (a process called quote removal).
As you can see, this is not a valid sed command, but that doesn't even come into play - see below.
>\/\]\/g is interpreted by the shell (bash), because it starts with output-redirection operator >; after quote removal, the shell sees >/]/g, tries to open file /]/g for writing, and fails, because your system doesn't have a subdirectory named ] in its root directory.
bash tries to open an output file specified by a redirection before running the command and, if it fails to open the file, does not run the command - which is what happened here:
bash complained about the nonexistent target directory and aborted processing of the command - sed was never even invoked.
Upshot:
In a string that is neither enclosed in single nor in double-quotes, you must \-quote:
all metacharacters: | & ; ( ) < > space tab
additionally, to prevent accidental pathname expansion (globbing): * ? [
Also note that if you need to quote (escape) characters for sed,you need to add an extra layer of quoting; for instance to instruct sed to use a literal . in the regex, you must pass \\. - two backslashes - so that sed sees the properly escaped \..
Given the above, it is much simpler to (habitually) use single quotes around your sed command, because it ensures that the string is passed as is to sed.
Let's compare a working version of your command to the one from Avinash Raj's answer (leaving out the -r for brevity):
sed s/\%\>\/\]\/g # ok - all metachars. \-quoted, others are, but needn't be quoted
sed s/%\>/]/g # ok - minimum \-quoting
sed 's/%>/]/g' # simplest: single-quoted command
I'm not sure whether I got the question correctly. If you want to replace either % or > by ] then sed is not required here. Use tr in this case:
tr '%>' ']' < input.txt
If you want to replace the sequence %> by ] then the sed command as shown by #AvinashRaj is the way to go.

sed add line if not exists

I need to make a change in the php.ini configuration file via sed (or similar).
I need to add the following text:
extension=solr.so
The line has to be added as line number 941 in the configuration file. However, if the file is already there, it should not be added again.
I guess there are two approaches: 1) replace line 941 with the text, or 2) search for the text and add it to line 941 if there are not matches.
I have the following command that works fine, except that the line is added again if the script is run again:
sed '941i\
extension=solr.so' /etc/php5/apache2/php.ini > /etc/php5/apache2/php.ini
How can I make sure that this command does not add the line if it is already there?
The easiest way would be to test before using grep, for example:
grep -q -e 'extension=solr.so' file || sed '...'
Also, it is estrange that you need exactly that line. You should add it at the end, or something like that.
Also, note that taking the same file as input and output never should be done. This can damage the file badly. You should be using the -i sed parameter to do in-place editing.