I want to try to find between patterns substrings then replace it
Source example text:
bbllaahh pattern1 blaah _SUBSTRING_ blah blaah
bbblah bbllaahh pattern1 blah blaah _SUBSTRING_ blahh _SUBSTRING_ blaah blahh blah pattern2 blllah blaaah
blahh blllllah _SUBSTRING_ blaah pattern2 blluhhh
Expecting:
bbllaahh pattern1 blaah _SUBSTRING_ blah blaah
bbblah bbllaahh pattern1 blah blaah _REPLACE_ blahh _REPLACE_ blaah blahh blah pattern2 blllah blaaah
blahh blllllah _SUBSTRING_ blaah pattern2 blluhhh
Patterns is could be different, and could be one or more in string. Source text not be changed except a substring replacement
I found example for unix:
sed '/pattern1/,/pattern2/' - doesn't work
sed '/pattern1/{s/_SUBSTRING_/_REPLACE_/}' - it's work but I am not sure whether working for pattern2 (' was replace " for win)
I was try to mixing but it doesn't work:
sed "/pattern1/,/pattern2/{s/_SUBSTRING_/_REPLACE_/}" - doesn't work pattern1
sed "/pattern1/,{s/_SUBSTRING_/_REPLACE_}/pattern2/" - doesn't work
Also _SUBSTRING_ could be instead a one of some special cheractors(like a ")
P.S.: This i do in window environment with sed GnuWin32
This may work assuming you intend to find both pattern1 and pattern2 on the same line.
$ sed '/pattern1.*pattern2/s/_[^_]*_/_REPLACE_/g' input_file
bbllaahh pattern1 blaah _SUBSTRING_ blah blaah
bbblah bbllaahh pattern1 blah blaah _REPLACE_ blahh _REPLACE_ blaah blahh blah pattern2 blllah blaaah
blahh blllllah _SUBSTRING_ blaah pattern2 blluhhh
Related
I am trying to match nested text, including the line immediately prior to the nested text with sed or grep.
An example of what I'm working with:
pattern3
abcde
fghij
pattern3
pattern1
abcde
fghij
pattern1
pattern1
klmno
pattern1
pattern3
abcde
pattern1
pqrst
patterh3
fghij
Note that there are always four (4) spaces prefixing the nested text. Also, there may or may not be nested text after a matching pattern.
I'm interested in all pattern1 lines, plus the lines following pattern1 that are proceeded by spaces.
The output I'm looking for is:
pattern1
abcde
fghij
pattern1
pattern1
klmno
pattern1
pattern1
pqrst
I got close with:
sed -n '/^pattern1/,/^pattern1/p' data.txt
But it seems to skip nested text after the right hand side pattern1 match, and move onto the next iteration.
I also tried sed -n '/^\"pattern1\"$/,/^\"pattern1\"$/p' data.txt | sed '1d;$d' with no luck either.
With GNU sed:
sed -n '/pattern1/{p;:x;n;s/^ .*/&/;p;tx}' file
or simplified:
sed -n '/pattern1/{p;:x;n;p;/^ /bx}' file
Output:
pattern1
abcde
fghij
pattern1
pattern1
klmno
pattern1
pattern1
pqrst
Could you please try following.
awk '/pattern[23]/{flag=""} /pattern1/{flag=1} flag' Input_file
OR
awk '/pattern[^1]/{flag=""} /pattern1/{flag=1} flag' Input_file
Explanation: Adding explanation too here.
awk '
/pattern[^1]/{ ##Checking condition if a line is having string pattern with apart from digit 1 in it then do following.
flag="" ##Nullifying variable flag value here.
}
/pattern1/{ ##Checking condition here if a line is having string pattern1 then do following.
flag=1 ##Setting value of variable flag as 1 here.
}
flag ##Checking condition if value of flag is NOT NULL then print the line value.
' Input_file ##Mentioning Input_file name here.
$ awk '/^[^ ]/{f=/^pattern1$/} f' file
pattern1
abcde
fghij
pattern1
pattern1
klmno
pattern1
pattern1
pqrst
This might work for you (GNU sed):
sed '/^\S/h;G;/pattern1/P;d' file
Store the current pattern in the hold space and append it to each line. If the current pattern is pattern1, print the current line and/or delete the current line.
I have been struggling to figure out how to 'unparse' lines in an log file (with 2 new line delimiters - '#' and '|') so all lines related to one time stamp are on one line.
Example:
2016-03-22 blah blah blah
|blah blah
|blah blah blah
#blah
|blah blah blah
2016-03-22 blah blah blah
|blah blah blah
#blah blah
#blah blah blah
|blah
Required Output
2016-03-22 blah blah blah |blah blah |blah blah blah #blah |blah blah blah
2016-03-22 blah blah blah |blah blah blah #blah blah #blah blah blah |blah
I thought I had this sussed simply by using xarg to put everything on one line then using sed to add new lines at 2016 but i discovered there is a limit on characters on one line and the log file is so big xargs was creating multiple lines.
Removing the carriage returns from lines starting with | and # would solve this but can't fathom how to do this either.
I've searched on here and found a few people posting similar questions but I can't interpret some of the solutions to fit in with my issue as I'm not familiar enough with sed/awk/xargs.
Would appreciate if anyone can offer some suggestions.
Thanks
You can use this awk command:
awk '/^[0-9]{4}(-[0-9]{2}){2}/ {
if (p!="")
print p
p=$0
next
}
{
p = p OFS $0
}
END {
print p
}' file
2016-03-22 blah blah blah |blah blah |blah blah blah #blah |blah blah blah
2016-03-22 blah blah blah |blah blah blah #blah blah #blah blah blah |blah
anubhava's answer works but it buffers the entirety of each line before printing it.
This prints as it reads each input line.
awk '{printf "%s%s", /^[|#]/?OFS:(NR>1)?"\n":"", $0} END{print ""}'
/^[|#]/ match lines starting with # or |
?OFS if matched lead with OFS (output field separator, space by default)
: otherwise
(NR>1) if we aren't on the first line
?"\n" output a newline
:"" otherwise output a blank (to avoid a blank line at the top of the output)
END{print ""} make sure we end the last line with a newline
This might work for you (GNU sed):
sed ':a;N;/\n....-..-.. /!s/\n/ /;ta;P;D' file
Read two lines into the pattern space and if the newline is not the start of a new record, replace it by a space and repeat i.e. append another line to the existing one etc.
If the line appended is the start of a new record, print the first line, delete it and repeat.
Remove the newlines, add a newline at the end of the line and insert newlines before each 2016:
echo '2016-03-22 blah blah blah
|blah blah
|blah blah blah
#blah
|blah blah blah
2016-03-22 blah blah blah
|blah blah blah
#blah blah
#blah blah blah
|blah ' | tr -d '\n' | sed -e 's/$/\n/' -e 's/2016-/\n2016-/g'
But how to merge lines (only words from lines), when this word exists in both files?
All words are changing automaticaly and files 1.txt and 2.txt are changing automatically too as part of package manager's script in Gnome 2 environment. And "link" means http://link
example INPUT:
1.txt contains detected http and version of packages:
link1/autotools-dev_20100122.1
link4/debhelper_8.0.0
link5/dreamchess_0.2.0
link5/dreamchess_0.2.0-2
link7/quilt_0.48
link7/quilt_0.48-7
link34/quilt-el_0.46.2
link34/quilt-el_0.46.2-1
2.txt contains needed extensions of packages:
autotools-dev_*.diff.gz
debhelper_*.diff.gz
debhelper_*.orig.tar.gz
libmxml-dev_*.diff.gz
libmxml-dev_*.dsc
libmxml-dev_*.orig.tar.gz
libsdl1.2-dev_*.diff.gz
libsdl1.2-dev_*.dsc
libsdl1.2-dev_*.orig.tar.gz
libsdl-image1.2-dev_*.diff.gz
libsdl-image1.2-dev_*.dsc
libsdl-image1.2-dev_*.orig.tar.gz
quilt_*.diff.gz
DESIRED OUTPUT to file 3.txt:
link1/autotools-dev_20100122.1.diff.gz
link4/debhelper_8.0.0.diff.gz
link4/debhelper_8.0.0.orig.tar.gz
libmxml-dev_*.diff.gz
libmxml-dev_*.dsc
libmxml-dev_*.orig.tar.gz
libsdl1.2-dev_*.diff.gz
libsdl1.2-dev_*.dsc
libsdl1.2-dev_*.orig.tar.gz
libsdl-image1.2-dev_*.diff.gz
libsdl-image1.2-dev_*.dsc
libsdl-image1.2-dev_*.orig.tar.gz
link7/quilt_0.48.diff.gz
link7/quilt_0.48-7.diff.gz
So needed script, which automaticaly detects common package name in files 1.txt and 2.txt and to file 3.txt suitable inserts to the same line where package name exist:
http and version from file 1.txt
extension from file 2.txt
lines from file 2.txt which not contain package name in file 1.txt
pattern1
a
b
pattern2
cd
pattern1
re
pattern2
gh
pattern1
ef
pattern2
qw
e
I can show all matching pattern by
sed -n '/pattern1/,/pattern2/p'
Choose the second matching pattern or any Nth by
awk -vM=2 '(x+=/pattern1/)==M&&x+=/pattern2/' file
pattern1
re
pattern2
Print only last matching pattern by
awk 'x+=/pattern1|pattern2/{!y++&&B="";B=B?B"\n"$0:$0;x==2&&y=x=0}END{print B}' file
pattern1
ef
pattern2
But how can I print for example the last/first 2 or Nth matching block pattern?
pattern1
re
pattern2
pattern1
ef
pattern2
This might work for you (GNU sed):
sed -n '/pattern1/,/pattern2/{p;/pattern2/{H;x;s///2;x;T;q}}' file
This prints the first 2 matches of pattern1 through pattern2 and then quits.
sed -nr '/pattern1/,/pattern2/H;$!b;x;s/.*((pattern1.*){2})$/\1/p' file
This prints the last 2 matches of pattern1 through pattern2.
In Bash ...
I know how to right pad with printf
printf "%-10s" "potato"
I know how to truncate with printf
printf "%.10s" "potatos are my best friends"
How can I do both at the same time?
LIST="aaa bbbbb ccc ddddd"
for ITEM in $LIST; do
printf "%-.4s blah" $ITEM
done
This prints
aaa blah
bbbbb blah
ccc blah
ddddd blah
I want it to print
aaa blah
bbbb blah
ccc blah
dddd blah
I'd rather not do something like this (unless there's no other option):
LIST="aaa bbbbb ccc ddddd"
for ITEM in $LIST; do
printf "%-4s blah" $(printf "%.4s" "$ITEM")
done
though, obviously, that works (it feels ugly and hackish).
You can use printf "%-4.4s for getting both formatting in output:
for ITEM in $LIST; do printf "%-4.4s blah\n" "$ITEM"; done
aaa blah
bbbb blah
ccc blah
dddd blah
I have files like:
text2insert
filewithpattern
and also known:
pattern
How can i insert lines from text2insert into filewithpattern but after the pattern line?
Using bash 2.05b
UPDATE:
Before filewithpattern should look like:
garbage
pattern1
pattern2
garbage
and after:
garbage
pattern1
text2insert lines
text2insert lines
text2insert lines
pattern2
garbage
sed -e '/pattern/r text2insert' filewithpattern
awk 'FNR==NR{ a[c++]=$0;next }
/pattern1/{g=1;next}
/pattern2/{g=0;next}
g{
for(i=1;i<=c;i++){
print a[i]
}
}' text2insert filewithpattern
And why do you need "garbage" in your output? Your previous question seems not to include "garbage"