Como retirar os primeiros caracteres X da string usando sed?

126

Estou escrevendo um shell script para Linux embarcado em uma pequena caixa industrial. Eu tenho uma variável que contém o texto pid: 1234e quero remover os primeiros caracteres X da linha, para que apenas 1234 permaneçam. Eu tenho mais variáveis ​​que preciso "limpar", então preciso cortar os primeiros caracteres X e ${string:5}não funcionar por algum motivo no meu sistema.

A única coisa que a caixa parece ter é sed.

Estou tentando fazer o seguinte funcionar:

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

Alguma ideia?

Kokesh
fonte
10
Se ${string:5}não funcionar, você não está usando o Bash ou outro shell que suporte essa sintaxe. Qual shell e versão você está usando? Como é o seu shebang? Meu palpite é que você está usando sh(como dash) ou possivelmente zsh.
Pausado até novo aviso.

Respostas:

0

Isso também fará o trabalho:

echo "$pid"|awk '{print $2}'
Arnaud F.
fonte
27
Esta pergunta é a primeira ocorrência de "pular os primeiros N caracteres na cadeia". Você não respondeu a pergunta.
JWW
Isso parece não funcionar, e se funcionar, você pode explicar como
Alexander Mills
Funciona no meu sistema. Pode haver um problema com seu separador de campos, tente awk -F": " '{print $2}'. Ainda assim, não é minha solução favorita.
Mkuther
197

O seguinte deve funcionar:

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

Você tem certeza de que basho shell está executando seu script?

Até o compatível com POSIX

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

seria preferível usar um processo externo, embora isso exija que você codifique os 5 na forma de um padrão de comprimento fixo.

chepner
fonte
1
Você também pode especificar o comprimento com um segundo parâmetro: ${var:5:2}iniciará 1e retornará 12.
Max Candocia 29/03
107

Aqui está um método conciso para cortar os primeiros caracteres X usando cut(1). Este exemplo remove os 4 primeiros caracteres cortando uma substring começando com o 5º caractere.

echo "$pid" | cut -c 5-
Randy the Dev
fonte
2
Esta é a solução mais simples!
Brandon
2
Tecnicamente, o OP solicitou o sed, mas acho que esta é a melhor solução para "Como posso retirar os primeiros caracteres X da string [em um terminal / bash]" Quando usado em combinação com o git, é interessante:git log --pretty=oneline | cut -c 42- | head
marksiemers
1
+1 Solução simples e útil. Quando eu tinha o URL como http: // <example.com> e para cortar o protocolo 'http: //', tenho que dizer como 8 caracteres em vez de 7. Não sei , mas foi assim que funcionou para mim.
Santosh Kumar Arjunan
1
Santosh Kumar Arjunan: isso ocorre porque o exemplo "echo" $ pid "| cut -c 4-" atualmente não está cortando os primeiros 4 caracteres, mas extrai a substring a partir do 4º caractere. Portanto, ele realmente corta os 3 primeiros caracteres. Assim, se você quer cortar 7 primeiros caracteres, você quer extrair tudo de 8 caracteres e, portanto, na verdade, fazer "cut -c 8-"
al-ash
1
@DeanHiller cut -c ${LEN}-. As chaves são usadas para concatenar a sequência com caracteres variáveis ​​válidos, a fim de distinguir qual é a variável e o que não é. Se você quiser obter mais informações, consulte "concatenação de cadeias de caracteres de variável bash" para obter mais recursos sobre por que / como isso funciona.
JustCarty 14/04
46

Use a -ropção ("use expressões regulares estendidas no script") sedpara usar a {n}sintaxe:

$ echo 'pid: 1234'| sed -r 's/^.{5}//'
1234
Mark Longair
fonte
1
como seria o caso, se eu quisesse retirar os últimos caracteres X de uma string?
Kokesh
5
@Kokesh: você pode fazer sed -r 's/.{5}$//'para tirar os últimos 5 caracteres em vez
Mark Longair
7
Você pode fazer isso sem o -r( -Eno OS X, IIRC) se você escapar do aparelho (embora não saiba se isso funciona no OS X).
Pausado até novo aviso.
2
@ Dennis: Acabei de verificar - escapar das chaves (e deixando de fora -r/ -E) funciona no OS X.
Gordon Davisson
15

Corte os dois primeiros caracteres da string:

$ string="1234567890"; echo "${string:2}"
34567890
dtp70
fonte
@ dtp70 Muito obrigado por uma resposta genérica, funcionou muito bem!
wolfram77
10

conduza através de awk '{print substr($0,42)}'onde 42 é um a mais que o número de caracteres a serem descartados. Por exemplo:

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

As chances são de que você também terá cut. Se então:

[me@home]$ echo "pid: 1234" | cut -d" " -f2
1234
Shawn Chin
fonte
1
O problema cuté que ele não lida com seqüências de espaço em branco de maneira sensata, usando tr -s ' 'para "espremer" espaços faz com que ele se comporte melhor.
Thor
1
Não é para ser uma ferramenta de cantar e dançar; é simples e faz o que diz na lata e está amplamente disponível. Deve funcionar bem para os requisitos mencionados e certamente é mais robusto do que cortar caracteres fixos de posições específicas.
Shawn Chin
5

Bem, tem havido soluções aqui com sed, awk, cute usando basha sintaxe. Eu só quero jogar em outra variante de conformidade POSIX:

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

-cinforma à cauda na qual o deslocamento de byte deve começar, contando desde o final dos dados de entrada, mas se o número começa com um +sinal, é do início dos dados de entrada até o final.

Mecki
fonte
4

Outra maneira, usando em cutvez de sed.

result=`echo $pid | cut -c 5-`
Evgeny
fonte
Ele quer remover os 4 primeiros caracteres. Isso recebe os 4 primeiros caracteres.
MM.
2

Eu encontrei a resposta em puro sed fornecida por esta pergunta (é verdade, postada depois que essa pergunta foi postada). Isso faz exatamente o que você pediu, exclusivamente no sed:

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

O ponto em sed '/./) é o que você deseja corresponder. Sua pergunta é exatamente o que eu estava tentando fazer, exceto que, no meu caso, eu queria corresponder uma linha específica em um arquivo e descomentá-la. No meu caso, foi:

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

O -iseguinte sedé editar o arquivo no local (remova essa opção se desejar testar sua expressão correspondente antes de editar o arquivo).

(Publiquei isso porque queria fazer isso inteiramente com o sed, conforme a pergunta e nenhuma das respostas anteriores resolveu esse problema.)

treehead
fonte
1

Em vez de remover n caracteres desde o início, talvez você possa extrair os dígitos diretamente. Igual a...

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

Essa pode ser uma solução mais robusta e parece mais intuitiva.

user1751825
fonte