I'm trying to change a few include statements in some C code for a piece of software I'm going to be distributing on a cluster. I've gone wrong with a for loop using sed. I would like to replace all instances of "htslib/" in between lines 242 and 246 of my code with "/opt/htslib/gcc48_1.2.1/include/hstlib/". It sounded simple enough, so I tried it in a for loop to recurse all files in a directory and change the lines that matched. My command was the following:
for i in `grep -rl 'htslib/bgzf.h' *`; do sed -i '242,246s/htslib\/opt\/htslib\/gcc48_1.2.1\/include\/htslib\//g' $i; done
However, I get an extra trailing slash after "htslib" in the replacement, so that it looks like this:
/opt/htslib/gcc48_1.2.1/include/htslib//bgzf.h
If it helps, the include statement started out looking like this:
htslib/bgzf.h
Thank you for any and all perspectives.
Related
I would like to input some text like this:
foo
stuff
various stuff
could be anything here
variable number of lines
bar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important
and get out this:
foo
teststuff
bar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important
So far I've read and messed around with using sed, grep, and pcregrep and not been able to make it work. It looks like I could probably do such a thing with Vim, but I've never used Vim before and it looks like a royal pain.
Stuff I've tried includes:
sed -e s/foo.*bar/teststuff/g -i file.txt
and
pcregrep -M 'foo\s+bar\s' file.txt | xargs sed 's/foo.*bar/teststuff/g'
I'm not sure if it's just that I'm not using these commands correctly, or if I'm using the wrong tool. It's hard for me to believe that there is no way to use the terminal to find and replace wildcards that span lines.
For clarity, simplicity, robustness, maintainability, portability and most other desirable qualities of software, just use awk:
$ awk 'f&&/bar/{print "teststuff";f=0} !f; /foo/{f=1}' file
foo
teststuff
bar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important
Try this with GNU sed:
sed -e '/^foo/,/^bar/{/^foo/b;/^bar/{i teststuff' -e 'b};d}'
See: man sed
This might work for you (GNU sed):
sed '/foo/,/bar/cteststuff' file
This will replace everything between foo and bar with teststuff.
However what you appear to want is everything following foo before bar, perhaps:
sed '/foo/,/bar/cfoo\nteststuff\nbar' file
Please bear with me as I'm new to the forums and tried to do my research before posting this. What I'm trying to do is to use sed to look through multiple lines of a file and any line that contains the words 'CPU Usage" I want it to comment out that line and also 19 lines immediately after that.
Example file.txt
This is some random text CPU USAGE more random text
Line2
Line3
Line4
Line5
etc.
I want sed to find the string of text CPU usage and comment out the line and the 19 lines following
#This is some random text CPU USAGE more random text
#Line2
#Line3
#Line4
#Line5
#etc.
This is what I've been trying but obviously it is not working since I'm posting on here asking for help
sed '/\/(CPU Usage)s/^/#/+18 > File_name
sed: -e expression #1, char 17: unknown command: `^'
I'd like to be able to use this on multiple files. Any help you can provide is much appreciated!
GNU sed has a non-standard extension (okay, it has many non-standard extensions, but there's one that's relevant here) of permitting /pattern/,+N to mean from the line matching pattern to that line plus N.
I'm not quite sure what you expected your sed command to do with the \/ part of the pattern, and you're missing a single quote in what you show, but this does the trick:
sed '/CPU Usage/,+19 s/^/#/'
If you want to overwrite the original files, add -i .bak (or just -i if you don't mind losing your originals).
If you don't have GNU sed, now might be a good time to install it.
This can easily be done with awk
awk '/CPU Usage/ {f=20} f && f-- {$0="#"$0}1' file
When CPU Usage is found, set flag f=20
If flag f is true, decrements until 0 and for every time, add # in front of the line and print it.
Think this should work, cant test it, if anyone finds something wrong just let me know :)
awk '/CPU Usage/{t=1}t{x++;$0="#"$0}x==19{t=0;x=0}1' file
Looking for the syntax to find a pattern in a file and remove the leading character from only that pattern.
For example, find -16 and remove the # and save it to file.
Tried grep 12345-16 testfile2 | sed -e "s/^#//g" which works but need to capture all entries into the input file.
Example:
From this:
something here 12345-14
something here 12345-15
# something here 12345-16
to this:
something here 12345-14
something here 12345-15
something here 12345-16
suggestions would be much appreciated.
You can do it with just sed alone.
sed '/12345-16/s/^# *//' file
You can use -i option of sed to make in-file changes. /../ in front of sed is a regex which only makes changes on lines that has that pattern. All remaining lines will not be touched and be printed out as is.
You don't need g for global here since you are only removing the leading #. I have added a pattern of ^# * which means # or # followed by spaces at the start of the line. You can create your own pattern based on the structure of your file.
This should be extremely simple, but for the life of me I just can't get gnu-sed to do it this afternoon.
The file in question has lines that look like this:
PART NUMBER PART NUMBER QUANTITY WEIGHT -999 -4,999 -9,999
w/ UL APPROVAL
MIN-3
I need to prepend every line like the "MIN-3" line with a ">" character, and the only thing specifically differentiating those lines from the others are two things:
The first character is a space " ".
The lines do not contain a comma.
I've tried mostly things like any of the following:
/^ +[^,]+$/ s/^/>/
/^ +[\w\-]+$/ s/^/>/
/^ +(\w|\-)+$/ s/^/>/
I will admit, I am somewhat new to sed. :)
Edit: Answers that use perl, or awk could also be appreciated, though my initial target is sed.
try this:
sed '/^ [^,]*$/s/^/>/'
the output is, only the line with MIN-3 with leading >
sed default uses basic regex. so the + should be \+ in your script. I think that could be the problem killing your time. You could add -r however, to let sed use extended-regex.
According to your description this should do:
sed 's/^\([ ][^,]*\)$/> \1/' input
which matches the complete line if the line starts with a space and then contains anything but a comma until the end.
Here is a simple answer:
sed 's/^ [^,]*$/>&/'
I have several thousand large text files that I need to clean up. I need any line that ends with a comma to end with a comma followed by a period (,.).
I found the following, which works for every line except the last line. It must be close to what I need but I can't figure out how to make it work on the last line as well.
find . -name "*.txt" -print | xargs sed -i ':a;N;$!ba;s/,\n/,\.\n/g'
My data looks something like this:
0,0,0,193,17,.,.,
0,0,0,174,19,.,.,
0,0,0,124,14,.,.,
I need it to look like this:
0,0,0,193,17,.,.,.
0,0,0,174,19,.,.,.
0,0,0,124,14,.,.,.
sed 's/,$/,./'
($ means end of line.)