Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed remove first pattern and the last pattern from a string

I'm processing some file names here. I need to remove the ^0 from the end of every file in a specific directory. For example:

root/etc/data.1.2.3^0
root/etc/file.4.5.6^0
root/etc/fileA.7.8.9^0

I want to remove the root/etc/part and the weird ^0 part. So far I figured the following: sed -e 's:root/etc/::' to remove the root/etc/part. Now I'm confused about how to remove the ^0 part.

I tried:sed -e 's:root/etc/^0$::' and sed -e 's:root/etc/\^0$::', but none of them is working.

I think I did not parse ^ as a character in sed correctly since ^ means something else in sed.

like image 898
DavidKanes Avatar asked Apr 17 '26 03:04

DavidKanes


2 Answers

You can use

for f in *^0; do 
  mv "$f" $(sed -e 's:root/etc/\(.*\)\^0$:\1:' <<< "$f");
done

See the sed online demo:

s='root/etc/data.1.2.3^0
root/etc/file.4.5.6^0
root/etc/fileA.7.8.9^0'
sed 's:root/etc/\(.*\)\^0$:\1:' <<< "$s"

Output:

data.1.2.3
file.4.5.6
fileA.7.8.9

The pattern matches:

  • root/etc/ - a literal root/etc/ substring
  • \(.*\) - Group 1 (\1 placeholder refers to this value): any zero or more chars
  • \^ - a ^ char
  • 0 - a 0 char
  • $ - end of string.
like image 59
Wiktor Stribiżew Avatar answered Apr 18 '26 19:04

Wiktor Stribiżew


I tried:sed -e 's:root/etc/^0$::' and sed -e 's:root/etc/\^0$::', but none of them is working.

No, of course those wouldn't work. Both patterns match the string root/etc/^0 appearing at the end of the line.

I think I did not pares ^ as a character in sed correctly since ^ means something else in sed...

That's not the issue. The ^ is special only at the beginning of the pattern or the beginning of a subexpression (to anchor it to the beginning of the input line) and as the first character of character class (to negate the class). Anywhere else it is an ordinary character.

There are various ways you could approach the problem. One would be to use a capturing group in the pattern and a back-reference in the replacement, as demonstrated in your other answer. Another would be simply to perform two s commands per line:

sed -e 's,^root/etc/,,; s,\^0$,,' 

The commands must be separated by a newline or semicolon. Note that you do need to escape the ^ at the beginning of the pattern in the second s command, as shown, for it to be interpreted as an ordinary character instead of an anchor.

like image 41
John Bollinger Avatar answered Apr 18 '26 18:04

John Bollinger