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 / user-503590

fozzybear's questions

Martin Hope
fozzybear
Asked: 2025-01-24 02:19:20 +0800 CST

Tornar a substituição de parâmetros em strings separadas por novas linhas mais eficiente

  • 7

O código a seguir deve demonstrar e ajudar a testar Pattern Matchingexpressões ineficientes em Parameter Substitutionuma variável de string separada por nova linha vs. matriz.

O objetivo é atingir pelo menos um desempenho equivalente ao grep, ao filtrar apenas git status -sresultados que envolvam indexalterações (total ou parcialmente staged).

Então, basicamente, cada entrada de alteração que começa com um sinalizador de status curto do Git, como [MTARDC](sinalizando uma alteração em estágio/índice), incluindo sinalizadores duplos (sinalizando alterações parcialmente em estágio no índice e worktree), exceto untrackedou unstaged-onlyalterações (começando com [ ?]).

Observe que Ros sinalizadores de alteração (renomear) podem ser seguidos por vários dígitos, veja também exemplos nos dados de teste abaixo (possivelmente até mesmo para índice e árvore de trabalho, ou seja, R104R104). Veja: formato curto do status do Git

Os dados de teste também contêm nomes de arquivos com caracteres especiais potencialmente problemáticos, como sequências de escape, espaço ou "e" comercial: [\ $*"].

Observe também que a substituição baseada em Pattern Matching requer uma negação de padrões, em comparação a um RegExfor grep com os mesmos resultados. Para imprimir os resultados, simplesmente comente as &>/dev/nullpartes.

#! /bin/bash

# Set extended pattern matching active
shopt -s extglob 

clear
unset -v tmpVar tmpArr

# Populate tmpVar and tmpArr for testing
for i in {1..3}; do
    tmpVar+=' A addedW1'[$i]$'\n'
    tmpVar+='A  addedI1'[$i]$'\n'
    tmpVar+='AM addedA1'[$i]$'\n'
    tmpVar+=' C copiedW1'[$i]$'\n'
    tmpVar+='C  copiedI1'[$i]$'\n'
    tmpVar+='CR copied A1'[$i]$'\n'
    tmpVar+=' D removedW1'[$i]$'\n'
    tmpVar+='D  removedI1'[$i]$'\n'
    tmpVar+='DM removedA1'[$i]$'\n'
    tmpVar+=' M modifiedW1'[$i]$'\n'
    tmpVar+='M  modifiedW1'[$i]$'\n'
    tmpVar+='MR modifiedA1'[$i]$'\n'
    tmpVar+=' R101 renamedW1'[$i]$'\n'
    tmpVar+='R102  renamedI2'[$i]$'\n'
    tmpVar+='R103D renamedA1'[$i]$'\n'
    tmpVar+=' T typeChangedW1'[$i]$'\n'
    tmpVar+='T  typeChangedI1'[$i]$'\n'
    tmpVar+='TM typeChangedA1'[$i]$'\n'
    tmpVar+='?? exec2.bin'[$i]$'\n'
    tmpVar+='?? file1.txt'[$i]$'\n'
    tmpVar+='?? test.launch2'[$i]$'\n'
    tmpVar+='A  file00 0.bin'[$i]$'\n'
    tmpVar+='A  file11*1.bin'[$i]$'\n'
    tmpVar+='A  file22\03457zwei.bin'[$i]$'\n'
    tmpVar+='A  file33\t3.bin'[$i]$'\n'
    tmpVar+='A  file44$4.bin'[$i]$'\n'
    tmpVar+='A  file55"$(echo EXE)"5.bin'[$i]$'\n'
    tmpVar+='M  exec1.bin'[$i]$'\n'
    tmpVar+=' M test.launch1'[$i]$'\n'
    tmpVar+=' M myproject/src/main/java/util/MyUtil.java'[$i]$'\n'
    tmpVar+='M  myproject/src/test/util/MyUtilTest.java'[$i]$'\n'
    tmpVar+='R104R104 myproject/src/test/util/MyUtil2Test.java'[$i]$'\n'
    tmpVar+=' A invalidAdd'[$i]$'\n'
    tmpVar+='R invalidRename'[$i]$'\n'
    tmpArr+=(" A addedW1[$i]")
    tmpArr+=("A  addedI1[$i]")
    tmpArr+=("AM addedA1[$i]")
    tmpArr+=(" C copiedW1[$i]")
    tmpArr+=("C  copiedI1[$i]")
    tmpArr+=("CR copied A1[$i]")
    tmpArr+=(" D removedW1[$i]")
    tmpArr+=("D  removedI1[$i]")
    tmpArr+=("DM removedA1[$i]")
    tmpArr+=(" M modifiedW1[$i]")
    tmpArr+=("M  modifiedW1[$i]")
    tmpArr+=("MR modifiedA1[$i]")
    tmpArr+=(" R101 renamedW1[$i]")
    tmpArr+=("R102  renamedI2[$i]")
    tmpArr+=("R103D renamedA1[$i]")
    tmpArr+=(" T typeChangedW1[$i]")
    tmpArr+=("T  typeChangedI1[$i]")
    tmpArr+=("TM typeChangedA1[$i]")
    tmpArr+=("?? exec2.bin[$i]")
    tmpArr+=("?? file1.txt[$i]")
    tmpArr+=("?? test.launch2[$i]")
    tmpArr+=("A  file00 0.bin[$i]")
    tmpArr+=("A  file11*1.bin[$i]")
    tmpArr+=("A  file22\03457zwei.bin[$i]")
    tmpArr+=("A  file33\t3.bin[$i]")
    tmpArr+=("A  file44$4.bin[$i]")
    tmpArr+=('A  file55"$(echo EXE)"5.bin['$i']')
    tmpArr+=("M  exec1.bin[$i]")
    tmpArr+=(" M test.launch1[$i]")
    tmpArr+=(" M myproject/src/main/java/util/MyUtil.java[$i]")
    tmpArr+=("M  myproject/src/test/util/MyUtilTest.java[$i]")
    tmpArr+=("R104R104 myproject/src/test/util/MyUtil2Test.java[$i]")
    tmpArr+=(" A invalidAdd[$i]")
    tmpArr+=("R invalidRename[$i]")
done

# Perf-test array or string var filtering via grep
_IFS="$IFS"; IFS=$'\n'
startTime="$EPOCHREALTIME"
grep '^[MTARDC]' <<<"${tmpArr[*]}" &>/dev/null
stopTime="$EPOCHREALTIME"
IFS="$_IFS"
echo
awk 'BEGIN { printf "ELAPSED TIME via grep filtering from ARRAY: "; print '"$stopTime"' - '"$startTime"' }'

# Perf-test array filtering via Pattern Matching in Parameter Substitution 
startTime="$EPOCHREALTIME"
printf '%s\n' "${tmpArr[@]/#[? ][?MTARDC]*([0-9]) *}" &>/dev/null
stopTime="$EPOCHREALTIME"
echo
awk 'BEGIN { printf "ELAPSED TIME via parameter substitution from ARRAY: "; print '"$stopTime"' - '"$startTime"' }'

# Perf-test string var filtering via Pattern Matching in Parameter Substitution 
startTime="$EPOCHREALTIME"
printf '%s\n' "${tmpVar//[? ][?MTARDC]*([0-9]) *([^$'\n'])?($'\n')}" &>/dev/null
stopTime="$EPOCHREALTIME"
echo
awk 'BEGIN { printf "ELAPSED TIME via parameter substitution from VAR: "; print '"$stopTime"' - '"$startTime"' }'

# RESULT:
#ELAPSED TIME via grep filtering from ARRAY: 0.054975
#ELAPSED TIME via parameter substitution from ARRAY: 0.00031805
#ELAPSED TIME via parameter substitution from VAR: 4.546

Como pode ser visto, grepé bom, mas a variante nº 2 (filtragem de matriz via Parameter substitution) é muito mais rápida, então, para matrizes grandes, há uma boa alternativa ao grep.

A filtragem de strings var via Parameter Substitution, por outro lado, é terrivelmente lenta.

Principalmente devido ao fato de que o padrão de correspondência não pode terminar com *(o que removeria tudo até o final da string da primeira correspondência), mas porque *([^$'\n'])?($'\n'), em vez disso, ele precisa, para corresponder (e remover) tudo em uma correspondência, até a próxima nova linha e, até certo ponto, devido à tmpVar//correspondência gananciosa.

Existe outra maneira/padrão para o exemplo, para processar strings var com Pattern Matching, da mesma forma que para array - sem usar a problemática e lenta correspondência de caracteres de negação de nova linha e para chegar perto da velocidade do exemplo de array?

bash
  • 1 respostas
  • 95 Views

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

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

    • 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

    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
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • 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
    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

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