ChatGPT解决这个技术问题 Extra ChatGPT

How can I strip first X characters from string using sed?

I am writing shell script for embedded Linux in a small industrial box. I have a variable containing the text pid: 1234 and I want to strip first X characters from the line, so only 1234 stays. I have more variables I need to "clean", so I need to cut away X first characters and ${string:5} doesn't work for some reason in my system.

The only thing the box seems to have is sed.

I am trying to make the following to work:

result=$(echo "$pid" | sed 's/^.\{4\}//g')

Any ideas?

If ${string:5} doesn't work then you're not using Bash or another shell that supports that syntax. What shell and version are you using? What does your shebang look like? My guess is that you're using sh (such as dash) or possibly zsh.
If these pid's are always integers, then selecting the number directly with regex will be a better, simpler solutioin than trying to remove a specific number of chacters from the start. I provided an answer to this effect, but it's being downvoted, because it doesn't do specifically what you've asked for. However, what you've asked may not be the best way to solve this particular problem.

c
chepner

The following should work:

var="pid: 1234"
var=${var:5}

Are you sure bash is the shell executing your script?

Even the POSIX-compliant

var=${var#?????}

would be preferable to using an external process, although this requires you to hard-code the 5 in the form of a fixed-length pattern.


You can also specify the length with a second parameter: ${var:5:2} will start at 1 and return 12.
a
al-ash

Here's a concise method to cut the first X characters using cut(1). This example removes the first 4 characters by cutting a substring starting with 5th character.

echo "$pid" | cut -c 5-

Technically the OP asked for sed, but I feel like this is the best solution for "How can I strip the first X characters from string [in a terminal/bash]" When used in combination with git, it is nice: git log --pretty=oneline | cut -c 42- | head
+1 Simple and helpful solution.. When I had the URL as http:// and to cut the protocol 'http://' I have to say as 8 chars instead of 7. I don't know, but that's how it worked for me.
Santosh Kumar Arjunan: that's because the example "echo "$pid" | cut -c 4-" is actualy not cuting first 4 characters but extracts substring starting from 4th character. Therefore it actually cuts first 3 characters. Thus, if you want to cut 7 first characters, you want to extract everything from 8th character and thus indeed do "cut -c 8-"
how do I do cut -c $LEN- so I can pass the amount which is in a variable?
@DeanHiller cut -c ${LEN}-. The curly braces are used to concatenate the string with valid variable characters, in order to distinguish what is the variable and what isn't. If you want more information on this, then look up "bash variable string concatenation" for more resources on why / how this works.
M
Mark Longair

Use the -r option ("use extended regular expressions in the script") to sed in order to use the {n} syntax:

$ echo 'pid: 1234'| sed -r 's/^.{5}//'
1234

how would it be for the case, if I would want to strip last X characters from a string?
@Kokesh: you can do sed -r 's/.{5}$//' to strip the last 5 characters instead
You can do it without the -r (-E in OS X, IIRC) if you escape the braces (don't know if that works in OS X, though).
@Dennis: I just checked -- escaping the braces (and leaving off -r / -E) works in OS X.
j
jww

Cut first two characters from string:

$ string="1234567890"; echo "${string:2}"
34567890

@dtp70 Thanks a lot a generic answer, it worked great!
B
Ben

pipe it through awk '{print substr($0,42)}' where 42 is one more than the number of characters to drop. For example:

$ echo abcde| awk '{print substr($0,2)}'
bcde
$

S
Shawn Chin

Chances are, you'll have cut as well. If so:

[me@home]$ echo "pid: 1234" | cut -d" " -f2
1234

Trouble with cut is that it doesn't handle sequences of whitespace sensibly, using tr -s ' ' to "squeeze" spaces makes it behave better.
It's not meant to be an all singing all dancing tool; it is simple and does as it says on the can and is widely available. It should work just fine for said requirements, and is certainly more robust that cropping out fixed characters from specific positions.
M
Mecki

Well, there have been solutions here with sed, awk, cut and using bash syntax. I just want to throw in another POSIX conform variant:

$ echo "pid: 1234" | tail -c +6
1234

-c tells tail at which byte offset to start, counting from the end of the input data, yet if the the number starts with a + sign, it is from the beginning of the input data to the end.


I really like this answer because it does exactly what OP asked for without using overcomplicated tools.
E
Evgeny

Another way, using cut instead of sed.

result=`echo $pid | cut -c 5-`

He wants to remove the first 4 characters. This gets the first 4 characters.
t
treehead

I found the answer in pure sed supplied by this question (admittedly, posted after this question was posted). This does exactly what you asked, solely in sed:

result=\`echo "$pid" | sed '/./ { s/pid:\ //g; }'\``

The dot in sed '/./) is whatever you want to match. Your question is exactly what I was attempting to, except in my case I wanted to match a specific line in a file and then uncomment it. In my case it was:

# Uncomment a line (edit the file in-place):
sed -i '/#\ COMMENTED_LINE_TO_MATCH/ { s/#\ //g; }' /path/to/target/file

The -i after sed is to edit the file in place (remove this switch if you want to test your matching expression prior to editing the file).

(I posted this because I wanted to do this entirely with sed as this question asked and none of the previous answered solved that problem.)


u
user1751825

Rather than removing n characters from the start, perhaps you could just extract the digits directly. Like so...

$ echo "pid: 1234" | grep -Po "\d+"

This may be a more robust solution, and seems more intuitive.


I'm not sure why this is getting downvotes. The OP asked for a specific type of solution, but the solution they were asking for was not the best fit for the problem they were trying to solve.
A
Arnaud F.

This will do the job too:

echo "$pid"|awk '{print $2}'

This question is the first hit for "skip first N characters in string". You did not answer the question.
This doesn't seem to work, and if it does, can you explain how
It does work on my system. There might be an issue with your field separator, try awk -F": " '{print $2}'. Still, not my favourite solution.
@jww It's a good idea sometimes to look beyond the question they're asking, to the problem they're trying to solve. This solves the OP's problem. From my experience, I've found that extracting data from strings based on character position, is rarely a robust way to solve a problem.