AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 422273
Accepted
lakerda
lakerda
Asked: 2018-02-07 04:58:25 +0800 CST2018-02-07 04:58:25 +0800 CST 2018-02-07 04:58:25 +0800 CST

Gerenciando expressões muito complexas com sed

  • 772

Estou tentando escrever um script que substitua essa linha:

 [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "

com essa linha:

# [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "

e isso adicionará essa nova linha:

[ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \D{%T} \W]\\$ "

para o /etc/bashrcarquivo. Basicamente, quero que o script comente as configurações antigas e adicione um carimbo de data/hora ao lado do nome de usuário no prompt (a nova configuração). Eu tentei fazer a primeira parte assim:

pattern=' [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "'
sudo sed 's/${pattern}/#${pattern}/' < /etc/bashrc 

Mas não funcionou, acho que é por causa dos caracteres especiais na string. Mas não tenho certeza de quais caracteres preciso escapar. A última parte deveria ser algo assim:

sed -i '  [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \D{%T} \W]\\$ "' /etc/bashrc

Apreciará alguma orientação.

Obrigado

shell-script sed
  • 3 3 respostas
  • 618 Views

3 respostas

  • Voted
  1. Best Answer
    Philippos
    2018-02-07T05:11:03+08:002018-02-07T05:11:03+08:00
    1. As aspas simples em seu sedscript impedem que o ${pattern}seja expandido. Você teria que usar aspas duplas (mas isso levaria ao problema mencionado com caracteres especiais)
    2. Use sedo endereçamento com o suficiente da linha fornecida para identificá-lo e, em seguida, insira o comentário assim:/^ *\[ *"$PS1 =/s/^/#/
    3. Use o acomando de sedpara anexar uma determinada linha

    No seu caso, você só quer adicionar algo à linha, então

    sed 's/\( *\[ "$PS1" = "..s-..v...$ " \] && PS1="\[.u@.h \)\(.W]..$ "\)/#\1\2\
    \1\\D{%T} \2/' /etc/bashrc 
    
    • 2
  2. domson
    2018-02-07T06:21:12+08:002018-02-07T06:21:12+08:00

    Se você deseja substituir uma linha inteira sem regex, também pode obter o número da linha primeiro:

    LNO=$(grep -FN "$pattern" </etc/bashrc | cut -d':' -f1)
    

    e substitua a linha pelo padrão comentado e nova linha:

    [ "$LNO" ] \
    && sed -i "${LNO}s/.*/#$pattern\n$newline/" /etc/bashrc
    

    Este também é mais claro para ler meses depois.

    Para fins de teste, sempre prefiro sed em um arquivo temporário primeiro (sem a opção -i) e renomeá-lo mais tarde para não prejudicar minha configuração.

    Mas também descobri que esse método não funciona com padrões contendo [,],$ and &, os padrões também precisam de algum mascaramento nesta ordem:

    pattern=${pattern//\[/\\\[}
    pattern=${pattern//\]/\\]}
    pattern=${pattern//\$/\\$}
    pattern=${pattern//\&/\\&}
    pattern=${pattern//\\/\\\\}
    

    o que leva à seguinte função:

    #!/bin/bash
    
    declare -a commentAndReplaceMask=('[' ']' '$' '&')
    function commentAndReplace () {
      local p="$1"  # pattern
      local s="$p" # sed pattern
      local r="$2"  # replacement
      local f="$3"  # file
    
      echo args:
      echo p: $p
      echo r: $r
      echo s: $s
    
      s=${s//\\/\\\\}
      r=${r//\\/\\\\}
      for m in ${commentAndReplaceMask[@]}; do
        s=${s//$m/\\$m}
        r=${r//$m/\\$m}
      done
    
      echo prepared for sed:
      echo p: $p
      echo r: $r
      echo s: $s
    
      LNO=$(grep -Fn "$p" <$f | cut -d':' -f1)
    
      [ "$LNO" ] \
      && sed "${LNO}s/.*/# $s\n$r/" <$f >${f}.tmp
    
      # mv "${f}.tmp" "$f"
    }
    
    commentAndReplace "$@"
    
    • 0
  3. dan
    2018-02-07T06:38:16+08:002018-02-07T06:38:16+08:00

    Para fazer esse tipo de substituição de padrão complexo por sed:

    sed 's/${pattern}/#${pattern}/'
    

    você tem que forçar a avaliação patterndesta forma:

    sed 's/'${pattern}'/#'${pattern}'/'
    

    Verifique se isso atinge exatamente o que você deseja no arquivo temporário antes de tentar tocar /etc/bashrce usar sudo(além disso, antes de usar, sudovocê deve verificar se realmente está usando o correto para evitar o uso de um falso).

    • 0

relate perguntas

  • Subtraindo a mesma coluna entre duas linhas no awk

  • Um script que imprime as linhas de um arquivo com seu comprimento [fechado]

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Dividir por delimitador e concatenar problema de string

  • MySQL Select com função IN () com array bash

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve