Por exemplo, dado:
USCAGoleta9311734.5021-120.1287855805
Eu quero extrair apenas:
US
Por exemplo, dado:
USCAGoleta9311734.5021-120.1287855805
Eu quero extrair apenas:
US
Respostas:
Provavelmente, o método mais eficiente, se você estiver usando o bashshell (e parece estar, com base nos seus comentários), é usar a variante de sub-string da expansão de parâmetros:
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
Isso definirá shortos dois primeiros caracteres de long. Se longfor menor que dois caracteres, shortserá idêntico a ele.
Esse método in-shell geralmente é melhor se você o fizer muito (como 50.000 vezes por relatório, como você mencionou), já que não há sobrecarga na criação do processo. Todas as soluções que usam programas externos sofrerão com essa sobrecarga.
Se você também deseja garantir um comprimento mínimo , pode prendê-lo antes da mão com algo como:
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
Isso garantiria que algo com menos de dois caracteres fosse preenchido à direita com pontos (ou qualquer outra coisa, apenas alterando o caractere usado ao criar tmpstr). Não está claro se você precisa disso, mas pensei em colocá-lo por completo.
Dito isto, existem várias maneiras de fazer isso com programas externos (como se você não tiver bashdisponível), algumas das quais são:
short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')
Os dois primeiros ( cute head) são idênticos para uma string de linha única - eles basicamente apenas devolvem os dois primeiros caracteres. Eles diferem no que cutfornecerá os dois primeiros caracteres de cada linha e heados dois primeiros caracteres de toda a entrada
O terceiro usa a awkfunção sub-string para extrair os dois primeiros caracteres e o quarto usa sedgrupos de captura (usando ()e \1) para capturar os dois primeiros caracteres e substituir a linha inteira por eles. Ambos são semelhantes a cut- eles entregam os dois primeiros caracteres de cada linha na entrada.
Nada disso importa se você tiver certeza de que sua entrada é uma única linha, todas elas têm um efeito idêntico.
printf '%s'em vez de echono caso de existirem caracteres estranhos na string: stackoverflow.com/a/40423558/895245 Para o POSIX obcecado: head -cnão é POSIX, cut -ce awk substrsão, sed \1não tenho certeza.
maneira mais fácil é
${string:position:length}
Onde isso extrai a $lengthsubstring de $stringem $position.
Este é um bash embutido; portanto, awk ou sed não é necessário.
Você chegou várias respostas boas e eu iria com o Bash builtin mim mesmo, mas já que você perguntou sobre sede awke ( quase ) ninguém mais oferecido soluções com base neles, eu oferecer-lhe estes:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'
e
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
O awkprimeiro deve ser bastante óbvio, mas aqui está uma explicação sed:
substr($0,1,2).
Se você estiver dentro bash, pode dizer:
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
Isso pode ser exatamente o que você precisa ...
Apenas grep:
echo 'abcdef' | grep -Po "^.." # ab
-Popção para torná-la mais curta. Todos os regexs entenderão esse padrão.
Você pode usar printf:
$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
Muito tarde, de fato, mas aqui está
sed 's/.//3g'
Ou
awk NF=1 FPAT=..
Ou
perl -pe '$_=unpack a2'
Se você deseja usar scripts de shell e não confiar em extensões não-posix (como os chamados bashismos), você pode usar técnicas que não requerem bifurcação de ferramentas externas, como grep, sed, cut, awk etc., que então torne seu script menos eficiente. Talvez a eficiência e a portabilidade do posix não sejam importantes no seu caso de uso. Mas, caso seja (ou apenas um bom hábito), você pode usar o seguinte método de opção de expansão de parâmetro para extrair os dois primeiros caracteres de uma variável de shell:
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
Isso usa a expansão de parâmetro "menor prefixo" para remover os dois primeiros caracteres (esta é a ${var#??}parte) e, em seguida, a expansão de parâmetro "menor sufixo" (a ${var%parte) para remover a cadeia de caracteres com exceção de dois caracteres, exceto o primeiro valor.
Este método foi descrito anteriormente nesta resposta à pergunta "Shell = Verifique se a variável começa com #". Essa resposta também descreve alguns métodos de expansão de parâmetros semelhantes que podem ser usados em um contexto ligeiramente diferente daquele que se aplica à pergunta original aqui.
Se o seu sistema estiver usando um shell diferente (não bash), mas o seu sistema tiver bash, você ainda poderá usar a manipulação de string inerente bashinvocando bashcom uma variável:
strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"
bashse você ainda não o estiver usando.
Só por diversão, acrescentarei alguns que, apesar de complicados e inúteis, não foram mencionados:
head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none
sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')
cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"
ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'
se mystring = USCAGoleta9311734.5021-120.1287855805
print substr(mystring,0,2)
imprimiria EUA
onde 0 é a posição inicial e 2 é como meny chars para ler
awk. Desculpe, eu não sabia dizer a princípio.
É isso que você procura?
my $string = 'USCAGoleta9311734.5021-120.1287855805';
my $first_two_chars = substr $string, 0, 2;
ref: substr
perl -e 'print substr $ARGV[0], 0, 2' 'USCAGoleta9311734.5021-120.1287855805'