Eu tenho um script de shell com este código:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
Mas o código condicional sempre é executado, porque hg st
sempre imprime pelo menos um caractere de nova linha.
- Existe uma maneira simples de remover o espaço em branco
$var
(comotrim()
no PHP )?
ou
- Existe uma maneira padrão de lidar com esse problema?
Eu poderia usar sed ou AWK , mas gostaria de pensar que há uma solução mais elegante para esse problema.
$ var=$(echo)
$ [ -n $var ]; echo $? #undesired test return
0
$ [[ -n $var ]]; echo $?
1
echo " This is a string of char " | xargs
. Se você no entanto, ter uma única citação no texto que você pode fazer o seguinte:echo " This i's a string of char " | xargs -0
. Note que eu menciono mais recente de xargs (4.6.0)test=`echo`; if [ -n "$test" ]; then echo "Not empty"; fi
, no entanto, serátest=`echo "a"`; if [ -n "$test" ]; then echo "Not empty"; fi
- portanto, deve haver mais do que apenas uma nova linha no final.echo $A | sed -r 's/( )+//g'
;Respostas:
Vamos definir uma variável que contenha espaços em branco iniciais, finais e intermediários:
Como remover todo o espaço em branco (indicado por
[:space:]
intr
):Como remover apenas os espaços em branco à esquerda:
Como remover apenas o espaço em branco à direita:
Como remover os espaços à esquerda e à direita - encadeie os
sed
s:Como alternativa, se o seu bash suportar, você poderá substituí-lo
echo -e "${FOO}" | sed ...
porsed ... <<<${FOO}
, desta forma (para espaços em branco à direita):fonte
tr
esed
por[[:space:]]
. Observe que ased
abordagem funcionará apenas na entrada de linha única . Para abordagens que funcionam com entrada de várias linhas e também usam os recursos internos do bash, consulte as respostas de @bashfu e @GuruM. Uma versão generalizada, inline da solução da @Nicholas Sushkin ficaria assim:trimmed=$([[ " test test test " =~ [[:space:]]*([^[:space:]]|[^[:space:]].*[^[:space:]])[[:space:]]* ]]; echo -n "${BASH_REMATCH[1]}")
alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'"
ao seu~/.profile
permite que você useecho $SOMEVAR | trim
ecat somefile | trim
.sed
solução que usa apenas uma única expressão ao invés de dois:sed -r 's/^\s*(\S+(\s+\S+)*)\s*$/\1/'
. Ele apara os espaços em branco à esquerda e à esquerda e captura todas as seqüências separadas por espaços em branco de caracteres que não sejam espaços em branco no meio. Aproveitar!|
, de modo a mantê-la como uma expressão única, em vez de várias.Uma resposta simples é:
Xargs fará o corte para você. É um comando / programa, sem parâmetros, retorna a string aparada, fácil assim!
Nota: isso não remove todos os espaços internos, portanto
"foo bar"
permanece o mesmo; NÃO se torna"foobar"
. No entanto, vários espaços serão condensados em espaços únicos,"foo bar"
tornando-se assim"foo bar"
. Além disso, ele não remove os caracteres de final de linha.fonte
xargs echo
apenas para ser detalhado sobre o que estou fazendo, mas o xargs por si só usará o eco por padrão.sed 's/ *$//'
como alternativa. Você pode ver axargs
nova linha como esta:echo -n "hey thiss " | xargs | hexdump
você vai notar0a73
oa
é a nova linha. Se você fizer o mesmo comsed
:echo -n "hey thiss " | sed 's/ *$//' | hexdump
verá0073
, nenhuma nova linha.a<space><space>b
ema<space>b
. 2. Ainda mais: ele vai se transformara"b"c'd'e
emabcde
. 3. Ainda mais: falharáa"b
etc.Existe uma solução que usa apenas os built-ins do Bash chamados curingas :
Aqui está o mesmo envolvido em uma função:
Você passa a string para ser cortada na forma de aspas. por exemplo:
Uma coisa boa dessa solução é que ela funcionará com qualquer shell compatível com POSIX.
Referência
fonte
s=" 1 2 3 "; echo \""${s%1 2 3 }"\"
apararia tudo do final, retornando a liderança" "
. Subbing1 2 3
with[![:space:]]*
diz a ele para "encontrar o primeiro caractere que não seja o espaço, depois o derrube e tudo mais". Usar em%%
vez de%
torna a operação de recorte do final gananciosa. Isso é aninhado em um corte não ganancioso desde o início; portanto, você efetua" "
o corte desde o início. Em seguida, troque%, # e * pelos espaços finais. Bam!/bin/sh
(apenas com/usr/xpg4/bin/sh
, mas não é isso que será usado nos scripts sh comuns).${var%%[![:space:]]*}
diz "remova devar
sua substring mais longa que começa com um caractere não espacial". Isso significa que você fica apenas com o (s) espaço (s) inicial (is), com o qual você remove posteriormente${var#..
. A linha a seguir (à direita) é o oposto.awk
,sed
,tr
,xargs
) apenas para os espaços em branco da guarnição de uma única corda é fundamentalmente insano - especialmente quando a maioria das conchas (incluindo bash) já fornecem seqüência nativa munging instalações out-of-the-box.O Bash possui um recurso chamado expansão de parâmetro , que, entre outras coisas, permite a substituição de cadeias com base nos chamados padrões (os padrões lembram expressões regulares, mas existem diferenças e limitações fundamentais). [linha original do flussence: Bash tem expressões regulares, mas estão bem escondidas:]
A seguir, demonstramos como remover todo o espaço em branco (mesmo do interior) de um valor variável.
fonte
${var/ /}
remove o primeiro caractere de espaço.${var// /}
remove todos os caracteres de espaço. Não há como aparar apenas espaços em branco à esquerda e à esquerda com apenas essa construção.Para remover todos os espaços do começo e do fim de uma string (incluindo caracteres de fim de linha):
Isso removerá espaços duplicados também:
Produz: 'essa string tem muitos espaços'
fonte
echo -n
mesmo?echo " my string " | xargs
tem a mesma saída.Tira um espaço à esquerda e um à direita
Por exemplo:
Resultado:
Tira todos os espaços à esquerda e à direita
Por exemplo:
Resultado:
fonte
'hello world ', 'foo bar', 'both sides '
Na seção Bash Guide sobre globbing
Para usar um extglob em uma expansão de parâmetro
Aqui está a mesma funcionalidade agrupada em uma função (NOTA: É necessário citar a string de entrada passada para a função):
Uso:
Se alterarmos a função a ser executada em um subshell, não precisamos nos preocupar em examinar a opção atual do shell para extglob, podemos apenas configurá-lo sem afetar o shell atual. Isso simplifica tremendamente a função. Também atualizo os parâmetros posicionais "no local" para não precisar nem de uma variável local
tão:
fonte
extglob
, usandoshopt -p
: basta escreverlocal restore="$(shopt -p extglob)" ; shopt -s extglob
no início de sua função eeval "$restore"
no final (exceto, se concedido, eval é mau…).[[:space:]]
poderia ser substituído por, bem, um espaço:${var##+( )}
e${var%%+( )}
trabalho, bem e eles são mais fáceis de ler.Você pode cortar simplesmente com
echo
:fonte
foo
contém um curinga? por exemplofoo=" I * have a wild card"
... surpresa! Além disso, isso reduz vários espaços contíguos em um.Eu sempre fiz isso com sed
Se houver uma solução mais elegante, espero que alguém a publique.
fonte
sed
?sed -e 's/\s*$//'
. Explicação: 's' significa pesquisa, o '\ s' significa todos os espaços em branco, o '*' significa zero ou muitos, o '$' significa até o final da linha e '//' significa substitui todas as correspondências por uma sequência vazia .Você pode excluir novas linhas com
tr
:fonte
Com os recursos de correspondência estendida de padrões do Bash ativados (
shopt -s extglob
), você pode usar este:{trimmed##*( )}
para remover uma quantidade arbitrária de espaços à esquerda.
fonte
/bin/sh -o posix
funciona também, mas desconfio.trimmed
? É uma coisa embutida ou a variável que está sendo cortada?fonte
read
armazenará na variável pelo seu nome $ 1 uma versão reduzida de seu valor $ {! 1}trim() { while [[ $# -gt 0 ]]; do read -rd '' $1 <<<"${!1}"; shift; done; }
read -rd '' str <<<"$str"
fará.Existem muitas respostas, mas ainda acredito que vale a pena mencionar meu roteiro recém-escrito porque:
"$*"
junta vários argumentos usando um espaço. se você deseja aparar e produzir apenas o primeiro argumento, use"$1"
em vezO script:
Uso:
Resultado:
fonte
[\ \t]
[[:space:]]
como em uma das outras respostas: stackoverflow.com/a/3352015/3968618Você pode usar a velha escola
tr
. Por exemplo, isso retorna o número de arquivos modificados em um repositório git, espaços em branco removidos.fonte
Isso funcionou para mim:
Para colocar isso em menos linhas para o mesmo resultado:
fonte
${var##Pattern}
obter mais detalhes. Além disso, este site explica os padrões do bash . Portanto, os##
meios removem o padrão dado da frente e os%%
meios removem o padrão dado da parte de trás. A+( )
parte é o padrão e significa "uma ou mais ocorrências de um espaço"OU
OU
OU
OU
Com base na expr soulution de moskit ...
OU
fonte
Eu já vi scripts usarem atribuição de variável para fazer o trabalho:
O espaço em branco é unido e aparado automaticamente. É preciso ter cuidado com os metacaracteres da concha (risco potencial de injeção).
Eu também recomendaria sempre a substituição de variáveis com aspas duplas nos condicionais do shell:
uma vez que algo como a -o ou outro conteúdo na variável pode alterar seus argumentos de teste.
fonte
$xyz
withecho
que faz a coalescência de espaços em branco, não a atribuição de variáveis. Para armazenar o valor aparado na variável em seu exemplo, você precisaria usarxyz=$(echo -n $xyz)
. Além disso, essa abordagem está sujeita a expansão de nome de caminho potencialmente indesejado (globbing).xyz
variável NÃO é aparado.fonte
echo $(echo "1 2 3")
(com dois espaços entre 1, 2 e 3).Eu simplesmente usaria o sed:
a) Exemplo de uso em string de linha única
Resultado:
b) Exemplo de uso em cadeia de linhas múltiplas
Resultado:
c) Nota final:
se você não gosta de usar uma função, para string de linha única, você pode simplesmente usar um comando "mais fácil de lembrar", como:
Exemplo:
Resultado:
O uso do descrito acima em seqüências de várias linhas também funcionará , mas observe que ele também cortará qualquer espaço múltiplo interno à direita / à direita, como o GuruM notou nos comentários
Resultado:
Portanto, se você se importa em manter esses espaços, use a função no início da minha resposta!
d) EXPLICAÇÃO da sintaxe sed "localizar e substituir" em seqüências de várias linhas usadas dentro da função trim:
fonte
Aqui está uma função trim () que apara e normaliza o espaço em branco
E outra variante que usa expressões regulares.
fonte
*
caractere na string de entrada expanda para todos os arquivos e pastas na pasta de trabalho atual. Por fim, se $ IFS estiver definido como um valor não padrão, o corte poderá não funcionar (embora isso seja facilmente solucionado com a adiçãolocal IFS=$' \t\n'
). O corte é limitado às seguintes formas de espaço em branco: espaços\t
e\n
caracteres.if
função:if [[ "$trimmed" =~ ' '*([^ ]|[^ ].*[^ ])' '* ]]
. Finalmente, a abordagem trata apenas de espaços, não de outras formas de espaço em branco (veja meu próximo comentário).if
linha com:[[ "$trimmed" =~ [[:space:]]*([^[:space:]]|[^[:space:]].*[^[:space:]])[[:space:]]* ]]
Use AWK:
fonte
$stripped_version=
echo $ var | awk '{gsub (/ ^ + | + $ /, "")} 1'``As atribuições ignoram os espaços em branco à esquerda e à direita e, como tal, podem ser usados para aparar:
fonte
echo "$var"
para ver o valor com espaços.var=$(echo $var)
mas eu não recomendo. Outras soluções apresentadas aqui são preferidas.Isso não tem o problema de globos indesejados, além disso, o espaço em branco interior não é modificado (supondo que
$IFS
esteja definido como padrão' \t\n'
).Ele lê a primeira linha nova (e não a inclui) ou o final da string, o que ocorrer primeiro, e retira qualquer mistura de espaço e
\t
caracteres iniciais e finais . Se você deseja preservar várias linhas (e também retirar novas linhas iniciais e finais), useread -r -d '' var << eof
; note, no entanto, que se a sua entrada contiver\neof
, ela será cortada imediatamente antes. (Outras formas de espaço em branco, ou seja\r
,\f
e\v
, se não despojado, mesmo se você adicioná-los a US $ IFS).fonte
Para remover espaços e tabulações da esquerda para a primeira palavra, digite:
cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-word.html
fonte
Isso removerá todos os espaços em branco da sua String,
/
substitui a primeira ocorrência e//
todas as ocorrências de espaços em branco na sequência. Ou seja, todos os espaços em branco são substituídos por - nadafonte
Este é o método mais simples que eu já vi. Ele usa apenas o Bash, são apenas algumas linhas, o regexp é simples e corresponde a todas as formas de espaço em branco:
Aqui está um exemplo de script para testá-lo:
fonte
^[[:space:]]*(.*[^[:space:]])?[[:space:]]*$
Python tem uma função
strip()
que funciona de maneira idêntica à do PHPtrim()
, então podemos fazer um pouco de Python embutido para criar um utilitário facilmente compreensível para isso:Isso irá aparar os espaços em branco à esquerda e à direita (incluindo novas linhas).
fonte
fonte
Eu descobri que precisava adicionar algum código de uma
sdiff
saída bagunçada para limpá-lo:Isso remove os espaços finais e outros caracteres invisíveis.
fonte
Removendo espaços em um espaço:
fonte