Me deparei com um código no script que adiciona ',' após cada 3 dígitos de trás para frente. o código considera apenas dados numéricos.
A seguir está o código.
sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' number.txt
number.txt
1234
12345
123456
resultado
1,234
12,345
123,456
1234,567
Alguém pode explicar o fluxo de código ..
sed
regular-expression
numeric-data
Couve de Dhaval
fonte
fonte
Respostas:
sed (o s tream ed itor) pode operar em s earch e modo de substituir usando expressões regulares . Há um pouco de escape específico do sed, mas para o próprio regex, você pode conferir a ferramenta de explicação do regexr :
(
Grupo de captura nº 1. Agrupa vários tokens e cria um grupo de captura para extrair uma substring ou usar uma referência anterior.^
Começando. Corresponde ao início da string.|
Alternação. Atua como um OR booleano. Corresponde à expressão antes ou depois do|
.[^
Conjunto negado. Corresponde a qualquer caractere que não esteja no conjunto.0-9
Alcance. Corresponde a um caractere no intervalo "0" a "9". Maiúsculas e Minúsculas..
Personagem. Corresponde a um "." personagem.]
)
(
Grupo de captura nº 2. Agrupa vários tokens e cria um grupo de captura para extrair uma substring ou usar uma referência anterior.[
Conjunto de caracteres. Corresponde a qualquer caractere no conjunto.0-9
Alcance. Corresponde a um caractere no intervalo "0" a "9". Maiúsculas e Minúsculas.]
+
Quantificador. Combine 1 ou mais do token anterior.)
(
Grupo de captura # 3. Agrupa vários tokens e cria um grupo de captura para extrair uma substring ou usar uma referência anterior.[
Conjunto de caracteres. Corresponde a qualquer caractere no conjunto.0-9
Alcance. Corresponde a um caractere no intervalo "0" a "9". Maiúsculas e Minúsculas.]
{3}
Quantificador. Combine 3 do token anterior.)
fonte
0-9 Range. Matches a character in the range "0" to "9". Case sensitive
"; PorCase sensitive
, você quer dizer dígitos Inglês? ou?O padrão captura (1) o início da linha ou algo que não é um dígito nem um ponto, seguido por (2) qualquer número de dígitos, pelo menos um, seguido por (3) exatamente três dígitos. Em seguida, os coloca de volta com uma vírgula entre (2) e (3), com efeito adicionando um separador de milhar. O primeiro grupo é necessário apenas para evitar tocar em partes fracionárias após um ponto decimal, pois não queremos
1.2345
nos transformar em1.2,345
.Observe que o padrão é escrito em expressões regulares básicas (BRE), exigindo barras invertidas na frente de cada uma
()
e{}
para torná-las especiais. Além disso, requer GNU sed, onde\+
e\|
também tem significados especiais no BRE como uma extensão . O comando seria melhor escrito como uma expressão regular estendida (sed -E
é suportada por muitas implementações sed):Além disso, o padrão faz apenas uma substituição, não inclui vários milhares de separadores no mesmo número. O
/g
final corresponderá várias vezes na mesma linha, mas ainda não processa os dados substituídos.1234567
vai se tornar1234,567
, não1,234,567
. Para corrigir isso, precisamos adicionar um loop:Aqui,
:a
é apenas um rótulo, e as finaista
t ests para uma substituição bem-sucedida, e salta de volta paraa
se um substituto foi feito, na verdade repetindo o processo tantas vezes quanto ele faz algo. Daí1234567
vai se transformar1,234,567
.fonte
sed 's/foo/bar/g' number.txt
: Lê o arquivonumber.txt
e substitui o padrão regexfoo
porbar
. Isso ocorrerá para todas as correspondências em cada linha (/g
).\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)
: Este é o padrão para substituir. Cada parte entre parênteses escapados\(…\)
é um "grupo de captura". O padrão interno é "capturado" para uso posterior.\(^\|[^0-9.]\)
: Encontre o início da linha^
ou\|
um caractere que não seja um número ou ponto[^0-9.]
. Essencialmente, encontra o caractere que precede um número.\([0-9]\+\)
: Encontre um ou mais números[0-9]\+
.\([0-9]\{3\}\)
: Encontre 3 numerais[0-9]\{3\}
.\1\2,\3
: substitua as correspondências acima pelos dois primeiros grupos de captura, seguidos pelo,
último grupo de captura. Em outras palavras, insira,
entre o segundo e o terceiro padrão.Por
sed
ser "ganancioso", ele tentará maximizar a duração da partida. Portanto, o grupo de captura final será os três últimos números do número.Nota: muitos dos caracteres "especiais" são escapados com
\
, por exemplo,\(…\)
e\{3\}
. Se suassed
"expressões regulares estendidas" suportadas com-E
ou-r
, você não precisaria escapar delas. Isso melhoraria a legibilidade.fonte