Can I used SED to replace a value within a range? - sed

I'm trying to replace a field with the proper value but I can't figure out how to do a blanket substitution. Here is what I have so far.
sed -i '' 's/AuthUserName=\[7000-8000]/AuthUserName=7325/g' "$f"
I'm trying to search all the files that contain AuthUserName=7000-8000 and make them all say AuthUserName=7325. I can do it individually by just having the AuthUserName=7000 for example and it will replace it with 7325 but I can't figure it out.
I tried to use =* but no success. Can anyone help me out? Thanks in advance.

For the numbers 7000 up to 7999 you could use a regular expression like 7[0-9][0-9][0-9]. Where each [0-9] simply stands for "one single digit from 0-9". You would then only have to treat the 8000 as a special case.

You can try something like
sed 's/AuthUserName=7[0-9][0-9][0-9]\|AuthUserName=8000/AuthUserName=7325/g'
or
sed 's/AuthUserName=7[[:digit:]][[:digit:]][[:digit:]]\|AuthUserName=8000/AuthUserName=7325/g'
[0-9] or [[:digit:]] are equivalent.
\| expresses alternative expression

Using perl and lookaround. First a test file:
$ cat file
asd
asd AuthUserName=700
asd AuthUserName=7000
asd AuthUserName=8000
asd AuthUserName=9000
asd AuthUserName=70000
The perl one-liner:
$ perl -pe 's/(?<=AuthUserName=)(7[0-9]{3}|8000)(?![0-9])/7325/g' file
ie. 7000-8000 preceeded by AuthUserName= and not followed by a digit, output:
asd
asd AuthUserName=700
asd AuthUserName=7325
asd AuthUserName=7325
asd AuthUserName=9000
asd AuthUserName=70000
In sed:
$ sed 's/\(AuthUserName=\)\(7[0-9]\{3\}\|8000\)\([^0-9]\|$\)/\17325\3/g' file

Related

Sed: capture the text between the first ( and )

I have the following badly formatted text:
<h1 id="page-title">ABCD TEXT TEXT ( QQQ-10-123-01)</h1>
<h1 id="page-title">ABCD TEXT TEXT (QQQ-10-123-02)</h1>
<h1 id="page-title">ABCD TEXT TEXT (QQQ-10-123-03 (QWERTY))</h1>
and need to get from it:
QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)
I.e. get only text between the first "(" and ")", at the moment doing the following:
sed -n "s/.*<h1 id=\"page-title\">.*(\(.*\))<\/h1>.*/\1/p" ./file.txt
and get:
QQQ-10-123-01
QQQ-10-123-02
QWERTY)
As you can see only the second line is being processed properly, since this line is most accurate. There are problems with ignoring possible whitespace and dealing with double entry "(" and ")". Can somebody give the right direction for solving the problems?
P.S. I need to parse over 2k lines; would there be a big difference in performance between sed and awk? As far as I have been reading and understood, sed should have a little benefit in speed. Is that really so?
Using sed
$ sed 's/[^(]*([[:space:]]\?\([^)]*)\?\)).*/\1/' input_file
QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)
$ sed -E 's/[^(]*\([[:space:]]?([^)]*\)?)\).*/\1/' input_file
QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)
Using any sed:
$ sed 's/[^(]*( *\(.*\)).*/\1/g' file
QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)

find sed regex for {}, ignoring the string in it

in a text file (on linux system) I have this string:
O\WIN_INFRASTRUKTUR{Windows Fabrik}\FIM{Forefront Identity Manager(Benutzer)}\EXTRA{}
Now, I want to replace the O\WIN_INFRASTRUKTUR{Windows Fabrik}, but I don't know what is standing in {}. It could be empty or text in it.
I try this, but without success:
sed -e 's/O\\WIN_INFRASTRUKTUR{[a-zA-Z0-9]}/O\\WIFI{}/g'
And that must be the Result:
O\WIFI{}\FIM{Forefront Identity Manager(Benutzer)}\EXTRA{}
Could anyone help me?
use the delimiter as end of your pattern, here it is } so take a class excluding this, any occurrence than your delimiter with [^}]*}
sed -e 's/O\\WIN_INFRASTRUKTUR{[^}]*}/O\\WIFI{}/g' YourFile
sed -e 's/WIN_INFRASTRUKTUR{[^}]*}/WIFI{}/g' <filename>
Thanks, it will be sucessful, but what is, if I want to have this result:
O\WIFI{}\EXTRA{}.
It doesn't matter if I do this:
sed -e 's/O\\WIN_INFRASTRUKTUR{[^}]*}\\FIM{[^}]*}/O\\WIFI{}/g'
than I get only this result: O\WIFI{}

Substitute all occurrences of n spaces with a single character

I would like to use sed (is this the best tool?) to go from this:
foo bar buzz fuzz
to this:
foo|bar|buzz|fuzz
How can this be done ?
Many thanks :).
$ sed 's/\s\s*/|/g' < input
Assuming you have 5 spaces between your items and they are in a file called test.txt:
sed -i "s/ /|/g" test
Use the [:SPACE:] POSIX Class
If the number of spaces could change, or might be a mix of spaces and tabs, then you want to use a POSIX class to replace a series of whitespace characters with a single pipe symbol globally within the current pattern space. For example:
$ echo 'foo bar buzz fuzz' | sed 's/[[:space:]]\+/|/g'
foo|bar|buzz|fuzz
If you have GNU sed:
sed -r 's/ +/|/g'

Printing text between regexps

I tried the '/pat1/,/pat2/p', but I want to print only the text between the patterns, not the whole line. How do I do that?
A pattern range is for multiline patterns. This is how you'd do that:
sed -n '/pat1/,/pat2/{/pat1\|pat2/!p}' inputfile
-n - don't print by default
/pat1/,/pat2/ - within the two patterns inclusive
/pat1\|pat2/!p - print everything that's not one of the patterns
What you may be asking for is what's between two patterns on the same line. One of the other answers will do that.
Edit:
A couple of examples:
$ cat file1
aaaa bbbb cccc
123 start 456
this is what
I want
789 end 000
xxxx yyyy zzzz
$ sed -n '/start/,/end/{/start\|end/!p}' file1
this is what
I want
You can shorten it by telling sed to use the most recent pattern again (//):
$ sed -n '/.*start.*/,/^[0-9]\{3\} end 0*$/{//!p}' file1
this is what
I want
As you can see, I didn't have to duplicate the long, complicated regex in the second part of the command.
sed -r 's/pat1(.*)pat2/\1/g' somefile.txt
I don't know the kind of pattern you used, but i think it is also possible with regular expressions.
cat myfile | sed -r 's/^(.*)pat1(.*)pat2(.*)$/\2/g'
you can use awk.
$ cat file
other TEXT
pat1 text i want pat2
pat1 TEXT I
WANT
pat2
other text
$ awk -vRS="pat2" 'RT{gsub(/.*pat1/,"");print}' file
text i want
TEXT I
WANT
The solution works for patterns that span multiple lines

repeat string in a line using sed

I would like to repeat each line's content of a file, any quick solution using sed.
supposed the input file is
abc def 123
The expected ouput is:
abcabc defdef 123123
sed 's \(.*\) \1\1 ' infile
This might work for you:
echo -e 'aaA\nbbB\nccC' | sed 's/.*/&&/'
aaAaaA
bbBbbB
ccCccC
sed 'h;G;s/\n//' file.txt
It's even simpler if you take advantage of the variable \0, which holds the string that was matched:
sed 's/.*/\0\0/'
Try this
awk '{print $0$0}' temp.txt