Text:
\item Further course of adolescent \uline{maturation and synaptic questions} to identify genes and circuit development factors associated with departures from normal developmental functioning, and \uline{points in prodromal stages where intervention} might particularly be targeted;
Goal: substitute \uline{ text... } to {\color{cname}\uline{ text... }} in the paragraph
Code:
#!/usr/local/bin/zsh
sed -i -n "96,300 {
s/\(\\\\uline{.*}\)/{\\\\color{cname}\1}/g
}" tmpName.tex
# issue: can't parse the second \uline !!
However, got the output like this:
\item Further course of adolescent {\color{cname}\uline{maturation and synaptic questions} to identify genes and circuit development factors associated with departures from normal developmental functioning, and \uline{points in prodromal stages where intervention}} might particularly be targeted;
Any help would be appreciated !
sed 's#\\uline{[^}]*}#{\\color{cname}&}#g' file
add the line range or -i if you needed.
test with your text:
kent$ cat f
\item Further course of adolescent \uline{maturation and synaptic questions}
\uline{points in prodromal stages where intervention} foo
kent$ sed 's#\\uline{[^}]*}#{\\color{cname}&}#g' f
\item Further course of adolescent {\color{cname}\uline{maturation and synaptic questions}}
{\color{cname}\uline{points in prodromal stages where intervention}} foo
Related
I am currently using sed to delete lines and subsequent line with various patterns from a file using the following the following code:
sed -i -e"/String1/,+1d" -e"/String2/,+1d," filename.txt
Works very well however I have a lot of patterns which vary from time to time.
Is it possible to put all patterns in another text file and make sed to delete all entries for patterns found in such file ?
Thanks
Here is an awk version
awk 'NR==FNR {a[$0]++;next} {for (i in a) if ($0~i) f=2} --f<0' list yourfile
NR==FNR {a[$0]++;next} store the list of lines to remove for file list in array a
for (i in a) for every line, loop through all lines in list
if ($0~i) f=2 if trigger line is found, set flag f to 2
--f<0 decrease flag f by one and test if it less than 0, if yes, print the line.
example
cat yourfile
one
two
three
four
five
six
seven
eight
nine
ten
eleven
cat list
three
eight
awk 'NR==FNR {a[$0]++;next} {for (i in a) if ($0~i) f=2} --f<0' list yourfile
one
two
five
six
seven
ten
eleven
Trying to stick with sed - at all cost, and being creative :-)
Consider using sed itself to generate the sed script that will perform the substitutions, based on the patterns file.
Important to note that this is solution will process each input file with one-pass, making it possible to use on large files/many patterns.
Proposed Solution:
sed -i -e "$(sed -e '/\//d;s/^/\//;s/$/\/,+1d/' < patterns.txt)" filename.txt
The embedded sed program (sed -e '/\//d;s/^/\//;s/$/\/,+1d/ ...) will convert the patterns.txt to a small sed script:
pattern.txt:
three
eight
foo/bar
Output: (noticed foo/bar ignored - contains '/')
/three/,+1d
/eight/,+1d
Notes, Limitations, etc:
One limit (of above implementation) is the delimiter, code remove any pattern with '/' to simplify generation of sed script, and to avoid potential injection. Possible to work around this limitation and allow for alternate delimiter (by escaping special characters in the pattern, or leveraging the '\%' addresses). May need additional testing.
Code assumes that the patterns are valid RE.
I have read sed info. In capture 3.5 :The s Command
There is a description:
The s command can be followed by zero or more of the following flags:
number
Only replace the numberth match of the regexp.
Note: the posix standard does not specify what should happen when you mix
the g and number modifiers, and currently there is no widely agreed
upon meaning across sed implementations. For GNU sed, the interaction
is defined to be: ignore matches before the numberth, and then match
and replace all matches from the numberth on.
I do not know how to use it ,who can give a example.
echo a1 | sed -n 's/\(a\)1/\13/p'
the result is no different with
echo a1 | sed -n 's/\(a\)1/\13/1p'
try this:
echo "hi hi hi" | sed 's/hi/hello/2'
echo "hi hi hi" | sed 's/hi/hello/3'
The number obviously only makes sense when there is more than one match.
sed 's/a/b/4' <<<aaaaa
aaaba
If there isn't a fourth match, obviously, no substitution takes place.
I want to keep the first id and remove everything afterwards with sed.
My line looks like
CAM_READ_0623233309 /library_id=CAM_LIB_002149 /sample_id=CAM_SMPL_003380 raw_id=G9ALM7U02F5HAW length=383 /IP_notice=?This genetic information downloaded from CAMERA may be considered to be part of the genetic patrimony of Denmark, the country from which the sample was obtained. Users of this information agree to: 1) acknowledge Denmark as the country of origin in any country where the genetic information is presented and 2) contact the CBD focal point identified on the CBD website (http://www.cbd.int/countries/) if they intend to use the genetic information for commercial purposes.?
and I just want :
CAM_READ_06232333
Capturing specific sequence:
sed -r 's/.*(CAM_READ_[0-9]+).*/\1/' input.txt
or
sed -e 's/.*\(CAM_READ_[0-9]\+\).*/\1/' input.txt
Capturing everything at the front, except whitespace characters:
sed -r 's/^(\S+).*/\1/' input.txt
Nice and easy sed statement:
sed 's/ .*$//'
s substitute
/ .*$/ match everything after the first space in the line
/ replace it with nothing
Command example:
echo "CAM_READ_0623233309 /library_id=CAM_LIB_002149 blah blah" | sed 's/ .*$//'
Command example output:
CAM_READ_0623233309
Now, of course, if you have multiple different types of lines within the same file that you're dealing with this will not work for you. But, your question above does not indicate this.
Given a file containing multiple lines with this format:
define('SOME_NAME', some_value);
How can sed be used to match SOME_NAME and replace some_value with some_other_value, for multiple different lines ?
This is a solution for one line:
sed -re "s|^(define *\('SOME_NAME'\s*,\s*).*(\);)|\1 some_other_value \2|" defs_file
To process a number of similar definitions in a file, I had to script outside sed (this example uses a bash version 4 associative array):
#!/bin/bash
declare -A args
args=([SOME_NAME1]=some_other_value1
[SOME_NAME2]=some_other_value2
[SOME_NAME3]=some_other_value3
[SOME_NAME4]=some_other_value4
[SOME_NAME5]=some_other_value5)
for arg in "${!args[#]}"
do
sed -i -re "s|^(define *\('$arg'\s*,\s*).*(\);)|\1 ${args[$arg]} \2|" defs_file
done
Is there a more elegant way to achieve this result that only relies on sed ?
This might work for you (GNU sed):
sed -r 's/$/\n#NAME:new_value/;s/([^,]*),[^\n]*\n.*#\1:([^#]*).*/\1,\2/;P;d' <<<"NAME,old_value"
This is a simplified example of yours; appending a lookup to the pattern space and then using regexp and back references to match and rearrange the output. See here for a detailed explanation.
N.B. In the example above (for brevity) I only included one lookup, in a real solution the lookup table would have several e.g. s/$/\n#NAME1:new_value1#NAME2:new_value2..../
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