2

I have a text file with the following pattern written to it:

TIME[32.468ms]  -(3)-............."TEXT I WANT TO KEEP"

I would like to discard the first part of each line containing

TIME[32.468ms]  -(3)-.............

To test the regular expression I've tried the following:

cat myfile.txt | egrep "^TIME\[.*\]\s\s\-\(3\)\-\.+"

This identifies correctly the lines I want. Now, to delete the pattern I've tried:

cat myfile.txt | sed s/"^TIME\[.*\]\s\s\-\(3\)\-\.+"//

but it just seems to be doing the cat, since it shows the content of the complete file and no substitution happens.

What am I doing wrong?

OS: CentOS 7

  • Tangentially, [the`cat`s are useless.](https://stackoverflow.com/questions/11710552/useless-use-of-cat) – tripleee Jul 01 '21 at 08:45

8 Answers8

2

With your shown samples, please try following grep command. Written and tested with GNU grep.

grep -oP '^TIME\[\d+\.\d+ms\]\s+-\(\d+\)-\.+\K.*' Input_file

Explanation: Adding detailed explanation for above code.

^TIME\[          ##Matching string TIME from starting of value here.
\d+\.\d+ms\]     ##Matching digits(1 or more occurrences) followed by dot digits(1 or more occurrences) followed by ms ] here.
\s+-\(\d+\)-\.+  ##Matching spaces91 or more occurrences) followed by - digits(1 or more occurrences) - and 1 or more dots.
\K               ##Using \K option of GNU grep to make sure previous match is found in line but don't consider it in printing, print next matched regex part only.
.*               ##to match till end of the value.


2nd solution: Adding awk program here.

awk 'match($0,/^TIME\[[0-9]+\.[0-9]+ms\][[:space:]]+-\([0-9]+\)-\.+/){print substr($0,RSTART+RLENGTH)}' Input_file

Explanation: using match function of awk, to match regex ^TIME\[[0-9]+\.[0-9]+ms\][[:space:]]+-\([0-9]+\)-\.+ which will catch text which we actually want to remove from lines. Then printing rest of the text apart from matched one which is actually required by OP.

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
1

This awk using its sub() function:

awk 'sub(/^TIME[[][^]]*].*\.+/,"")' file
"TEXT I WANT TO KEEP"
  • If there is replacement, sub() returns true.
Carlos Pascual
  • 1,106
  • 1
  • 5
  • 8
1
$ cut -d'"' -f2 file
TEXT I WANT TO KEEP
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
0

You may use:

s='TIME[32.468ms]  -(3)-............."TEXT I WANT TO KEEP"'
sed -E 's/^TIME\[[^]]*].*\.+//'

"TEXT I WANT TO KEEP"
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

The \s regex extension may not be supported by your sed.

In BRE syntax (which is what sed speaks out of the box) you do not backslash round parentheses - doing that turns them into regex metacharacters which do not match themselves, somewhat unintuitively. Also, + is just a regular character in BRE, not a repetition operator (though you can turn it into one by similarly backslashing it: \+).

You can try adding an -E option to switch from BRE syntax to the perhaps more familiar ERE syntax, but that still won't enable Perl regex extensions, which are not part of ERE syntax, either.

sed 's/^TIME\[[^][]*\][[:space:]][[:space:]]-(3)-\.*//' myfile.txt

should work on any reasonably POSIX sed. (Notice also how the minus character does not need to be backslash-escaped, though doing so is harmless per se. Furthermore, I tightened up the regex for the square brackets, to prevent the "match anything" regex you had .* from "escaping" past the closing square bracket. In some more detail, [^][] is a negated character class which matches any character which isn't (a newline or) ] or [; they have to be specified exactly in this order to avoid ambiguity in the character class definition. Finally, notice also how the entire sed script should normally be quoted in single quotes, unless you have specific reasons to use different quoting.)

If you have sed -E or sed -r you can use + instead of * but then this complicates the overall regex, so I won't suggest that here.

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

A simpler one for sed:

sed 's/^[^"]*//' myfile.txt
Darkman
  • 2,941
  • 2
  • 9
  • 14
0

If the "text you want to keep" always surrounded by the quote like this and only them having the quote in the line starting with "TIME...", then:

sed -n '/^TIME/p' file | awk -F'"' '{print $2}'

should get the line starting with "TIME..." and print the text within the quotes.

web
  • 105
  • 9
0

Thanks all, for your help. By the end, I've found a way to make it work:

echo 'TIME[32.468ms] -(3)-.............TEXT I WANT TO KEEP' | grep TIME | sed -r 's/^TIME\[[0-9]+\.[0-9]+ms\]\s\s-\(3\)-\.+//'

More generally,

grep TIME myfile.txt | sed -r ‘s/^TIME\[[0-9]+\.[0-9]+ms\]\s\s-\(3\)-\.+//’ Cheers, Pedro