Remover caracteres à direita do primeiro espaço no Bash

7
2492  some string continues here

Gostaria de converter isso para

2492

no Bash. Como eu faria isso?

Isso parece próximo, mas não está funcionando:

var="2492  some string continues here  "
echo ${var%[[:space:]]*}
    
por Joshua Soileau 12.04.2018 / 22:29

6 respostas

14

Porque existem vários espaços que você deseja usar

${var%%[[:space:]]*}
# ...^^

para remover a substring anterior mais longa que começa com um espaço

Com apenas um único % , você está removendo a seqüência mais curta de um espaço, seguida de zero ou mais caracteres, que é apenas o último espaço da string.

$ echo ">$var<"; echo ">${var%[[:space:]]*}<"; echo ">${var%%[[:space:]]*}<"
>2492  some string continues here  <
>2492  some string continues here <
>2492<

Se você está apenas procurando pela primeira palavra , você pode fazer isso:

read -r word rest_of_string <<<"$var"
echo "I have: $word"

Isso cuidará dos principais espaços em branco, supondo que você não tenha alterado a variável IFS.

    
por 12.04.2018 / 22:35
2

Existe a solução simples de usar %% ( ${var%% *} ) em vez de % ( ${var% *} ). Isso removerá tudo ( * ) depois de um espaço inicial.

$ var='2492  some string continues here'
$ echo "${var%% *}"
2492

Mas isso falhará se a string em var tiver algum espaço à esquerda. É possível remover os espaços iniciais com:

$ var=$' \t 2492  some string continues here  '
$ var="${var#"${var%%[![:space:]]*}"}"
$ echo "$var"
2492  some string continues here  
$ echo "${var%%[[:space:]]*}"
2492

Isso funciona mesmo se os espaços em branco forem espaços nas guias NL ou CR.

Regex

Talvez uma solução mais robusta seja usar um regex:

$ var=$' \t 2492  some string continues here  '
$ regex='^[[:space:]]*([^[:space:]]+)'
$ [[ $var =~ $regex ]] && var=${BASH_REMATCH[1]}
$ echo "$var"
2492
    
por 13.04.2018 / 04:58
2

Você também pode usar a ferramenta simples cut , que corta strings com base em um delimitador:

echo "$mystring" | cut -d' ' -f 1 

Onde:

  • -d' ' define o delimitador para um espaço
  • -f 1 fornece o primeiro campo (baseado no delimitador)
por 13.04.2018 / 10:29
1

Você pode usar a manipulação de string de shell nativa:

TEST="test  1234 foo"
SPLIT_VAR=${TEST/ */ }

Ele substituirá o primeiro padrão correspondente "*" (um espaço a qualquer coisa) e substituirá por "" (um espaço). Então você mantém a primeira palavra e o primeiro espaço.

Você pode ver o link para mais uso da manipulação de strings.

E como uma nota lateral, também funciona o shell menos evoluído (testado na implementação de ash do busybox).

    
por 13.04.2018 / 11:22
0

Para usar somente os comandos bash e builtin, você pode usar Separador de campos interno (IFS) e matrizes

set -f                # To prevent filename globbing when creating the array, as pointed out by Kusalananda in the comments
array=(2492 some string continues here)
set +f                # enable it again
IFS=" "
echo "${array[0]}"
unset IFS
    
por 13.04.2018 / 09:01
0

Se você não se importa com uma chamada externa, use o awk ou o sed:

$ string="first second third fourth"
$ echo "${string}" | awk '{print $1}' # will work even with tabs
first
$ echo "${string}" | sed -e "s/ .*$//" # will fail on leading whitespace
first
    
por 13.04.2018 / 07:55