I need to replace a particular range of characters in each line of a file.
I tried this
perl -i -pe 'r77,79c/XXX/g' file
I am trying to change the 77th to 79th characters to XXX using Perl, but above code is not working.
you want to replace chars at position [77-79] with XXX?
try
perl -i -piorig_* -e "substr($_,76,3)=XXX" file
a backup file called orig_file will be created cause of preventing possible dataloss..
perl -i -pe 's/.{76}\K.../XXX/' file
You wrote:
Actually i want to search a pattern in a file and whatever lines matching that pattern needs to be replaced to 50th & 51st character to XX
Using sed:
sed -r '/pattern/s/^(.{49})..(.*)$/\1XX\2/' file
sed "/pattern/ s/^\(.\{49\}\)../\1XX/" YourFile
we don't touch the end
Related
I have a txt file under CentOS in which I want to replace any "\t\n" with "\t\t". I tried this:
sed -i -E 's/\t\n/\t\t/g' myfile.txt
but it doesn't work. I don't know if CentOS doesn't support regex in sed.
Any help is appreciated!
p.s.
Input(two lines):
1\t2\t3\t$
4\t5\t6\t$
Output(one line):
1\t2\t\3\t\t4\t5\t6\t\t
In Editplus, the find regex is '\t\n' and the replace is '\t\t'. Then all lines ending with '\t\n' will become one line, and each '\n' is replaced by one additional '\t'.
p.s.
my file is read like this (cat -A myfile.txt)
You may use this perl command to join lines if previous line has a single tab:
perl -i -0777 -pe 's/(\S\t)\n(?!\z)/$1\t/g' excel.log
(?!\z) is a negative lookahead to fail this match for last line of the file.
You need to escape the backslashes.
sed -i -E 's/\\t\\n/\\t\\t/g' myfile.txt
I have lots of files that have lines that are in the following way:
#include "3rd-party/*lots folders*>
problem is that it ends with > instead of "
Is there a quick regex for sed to change that?
basically, if the line starts with #include "3rd-party, it should replace the last character to ".
Thanks in advance
You can use this:
sed -i '' '/^[[:blank:]]*#include "3rd-party/s/>$/"/' file
#include "3rd-party/*lots folders*"
Basically you can use:
sed '/^[[:space:]]*#include "3rd-party/s/>[[:space:]]*$/"/' file
Explanation:
/^[[:space:]]*#include/ is an address, a regular expression address. The subsequent command will apply to lines which start which optional space followed by an #include statement.
s/>[[:space:]]*$/"/ replaces > followed by optional space and the end of the line by a ".
Use the -i option if you want to change the file in place:
sed -i '/^[[:space:]]*#include/s/>[[:space:]]*$/"/' file
On a bunch of, let's say C files, use find and it's -exec option:
find . -name '*.c' -exec sed -i '/^[[:space:]]*#include/s/[[:space:]]*$/"/' {} \;
You can use sed for searching a pattern and doing an action on this line like
sed '/search_pattern/{action}' your_file
The action you want to do is replacing the last character in a line with >$ where > is your desired character and $ means that the searched character must be placed at the end of a line.
The action for doing this is the sedcommand s/// which work's like s/search_pattern/replace_pattern/.
This looks for your goal like:
sed '/#include "3rd-party/{s/>$/"/}' your_file
But since sed is a (s)tream (ed)itor you have to use sed's command flag -i to make your changes inline or pipe it with > to a new file.
Like this
sed -i '/#include "3rd-party/{s/>$/"/}' your_file
or like this
sed '/#include "3rd-party/{s/>$/"/}' your_file > new_file
Please let me know if this does your work.
I want to remove all the lines from a file that don't have the form:
something.something,something,something
For example if the file was the following:
A sentence, some words
ABCD.CP3,GHD,HDID
Hello. How are you?
A.B,C,D
dbibb.yes,whoami,words
I would be left with:
ABCD.CP3,GHD,HDID
A.B,C,D
dbibb.yes,whoami,words
I have tried to branch to the end of the sed script if I match the pattern I don't want to delete but continue and delete the line if it doesn't match:
cp $file{,.tmp}
sed "/^.+\..+,.+,.+$/b; /.+/d" "$file.tmp" > $file
rm "$file.tmp"
but this doesn't seem to have any affect at all.
I suppose I could read the file line by line, check if matches the pattern, and output it to a file if it does, but I'd like to do it using sed or similar.
You can use grep successfully:
grep -E '^[^.]+\.[^,]+,[^,]+,[^,]+$' file > temp
mv temp file
grep -E '^[^.]+\.[^.]+(,[^,]+){2}$'
Instead of deleting the lines which didn't satisfies the pattern, you could print the lines that matches this something.something,something,something pattern.
Through sed,
$ sed -n '/^[^.]*\.[^,]*,[^,]*,[^,.]*$/p' file
ABCD.CP3,GHD,HDID
A.B,C,D
dbibb.yes,whoami,words
Use inline edit option -i[suffix] to save the changes made.
sed -ni.bak '/^[^.]*\.[^,]*,[^,]*,[^,.]*$/p' file
Note: -i[suffix] make a backup if suffix is provided.
Through awk,
$ awk '/^[^.]*\.[^,]*,[^,]*,[^,.]*$/{print}' file
ABCD.CP3,GHD,HDID
A.B,C,D
dbibb.yes,whoami,words
I have the following test file
AAA
BBB
CCC
Using the following sed I can comment out the BBB line.
# sed -e '/BBB/s/^/#/g' -i file
I'd like to only comment out the line if it does not already has a # at the begining.
# sed -e '/^#/! /BBB/s/^/#/g' file
sed: -e expression #1, char 7: unknown command: `/'
Any ideas how I can achieve this?
Assuming you don't have any lines with multiple #s this would work:
sed -e '/BBB/ s/^#*/#/' -i file
Note: you don't need /g since you are doing at most one substitution per line.
Another solution with the & special character which references the whole matched portion of the pattern space. It's a bit simpler/cleaner than capturing and referencing a regexp group.
sed -i 's/^[^#]*BBB/#&/' file
I find this solution to work the best.
sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\ \1/' file
It doesn't matter how many "#" symbols there are, it will never add another one. If the pattern you're searching for does not include a "#" it will add it to the beginning of the line, and it will also add a trailing space.
If you don't want a trailing space
sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\1/' file
Assuming the BBB is at the beginning of a line, I ended up using an even simpler expression:
sed -e '/^BBB/s/^/#/' -i file
One more note for the future me. Do not overlook the -i. Because this won't work: sed -e "..." same_file > same_file.
sed -i '/![^#]/ s/\(^.*BBB.*$\)/#\ \1/' file
This doesn't work for me with the keyword *.sudo, no comments at all...
Ony the syntax below works:
sed -e '/sudo/ s/^#*/#/' file
Actually, you don't need the exclamation sign (!) as the caret symbol already negates whatever is inside the square brackets and will ignore all hash symbol from your search. This example worked for me:
sed -i '/[^#]/ s/\(^.*BBB.*$\)/#\ \1/' file
Comment all "BBB", if it's haven't comment yet.
sed -i '/BBB/s/^#\?/#/' file
If BBB is at the beginning of the line:
sed 's/^BBB/#&/' -i file
If BBB is in the middle of the line:
sed 's/^[^#]*BBB/#&/' -i file
I'd usually supply sed with -i.bak to backup the file prior to making changes to the original copy:
sed -i.bak '/BBB/ s/^#*/#/' file
This way when done, I have both file and file.bak and I can decide to delete file.bak only after I'm confident.
If you want to comment out not only exact matches for 'BBB' but also lines that have 'BBB' somewhere in the middle, you can go with following solution:
sed -E '/^([^#].*)?BBB/ s/^/#/'
This won't change any strings that are already commented out.
i have some strings with this pattern in some files:
domain.com/page-10
domain.com/page-15
....
and i want to replace them with something like
domain.com/apple-10.html
domain.com/apple-15.html
i have found that i can use sed command to replace them at a time but because after the numbers should something be added i guess i have to use regular expression to do it. but i don't know how.
sed -i.bak -r 's/page-([0-9]+)/apple-\1.html/' file
sed 's/page-\([0-9][0-9]*\)/apple-\1.html/' file > t && mv t file
Besides sed, you can also use gawk's gensub()
awk '{b=gensub(/page-([0-9]+)/,"apple-\\1.html","g",$0) ;print b }' file
sed -i 's/page-\([0-9]*\)/apple-\1.html/' <filename>
The ([0-9]*) captures a group of digits; the \1 in the replacement string references that capture and adds it as part of the replacement string.
You may want to use something like -i.backup if you need to keep a copy of the file without the replacements, or just omit the -i and instead use the I/O redirection method instead.
One more way to resolve the problem:
sed -i.bak 's/\(^.*\)\(page-\)\(.*\)/\1apple-\3.html/' Files
Here the searching patterns are stored and retrieved using references (\1, \2, \3).
This will work
sed 's/$/\.html/g' file.txt