Qual é a diferença entre o arquivo grep apple e o arquivo grep “apple”?

22

Qual é a diferença entre grep apple filee grep "apple" file? O que faz as aspas? Ambos parecem funcionar e fazem exatamente a mesma coisa (exibir a mesma linha).

John Stacen
fonte

Respostas:

45

As aspas afetam os caracteres que seu shell considera especiais e têm um significado sintático. No seu exemplo, isso não faz diferença porque applenão contém esses caracteres.

Mas considere outro exemplo: grep apple tree fileprocurará a palavra applenos arquivos treee file, enquanto grep "apple tree" fileprocurará a palavra apple treeno arquivo file. As aspas indicam ao bash que a palavra espaço em "apple tree"não inicia um novo parâmetro, mas deve fazer parte do parâmetro atual. grep apple\ tree fileproduziria o mesmo resultado, porque \diz ao bash para desconsiderar o significado especial do caractere a seguir e tratá-lo literalmente.

David Foerster
fonte
2
Isso também é visível com caracteres curinga. Se você o fizer grep a*b equations.txt, ele procurará a*b, a menos que exista um arquivo no diretório atual começando com ae terminando em b; nesse caso (porque (ba) sh expandirá os nomes dos arquivos na linha de comando), grep será chamado com complete parâmetros diferentes, resultando em resultados diferentes. Isso geralmente é mais um problema com o find, pois um comando como find . -name *.txtresultará em comportamento inesperado, se houver um arquivo txt no diretório atual. É melhor usar aspas neste caso.
fácil
4
Outro ponto importante é a diferença entre aspas duplas ( ") e aspas simples ( '). Aspas simples impedem a interpretação de certos caracteres, como $, enquanto as aspas duplas permitem a interpretação. Por exemplo grep '${USER}', procurará o texto ${USER}, enquanto grep "${USER}"procurará o texto que a variável USERcontém (por exemplo johnstacen).
Paddy Landau
23

As aspas duplas permitem a avaliação, as aspas simples impedem a avaliação, as aspas não permitem a expansão de caracteres curinga, quando usadas na linha de comando. Como exemplos planejados:

[user@work test]$ ls .
A.txt B.txt C.txt D.cpp

# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp

[user@work test]$ echo "*"
*

[user@work test]$ echo '*'
*

# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt

[user@work test]$ echo "*.txt"
*.txt

[user@work test]$ echo '*.txt'
*.txt

[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found

[user@work test]$ myname=is\ Fred; echo $myname
is Fred

[user@work test]$ myname="is Fred"; echo $myname
is Fred

[user@work test]$ myname='is Fred'; echo $myname
is Fred

A compreensão do modo como as aspas funcionam é essencial para entender o Bash. Por exemplo:

# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt

# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt

# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)

Você pode usar aspas simples para passar um comando por meio de uma variável. Aspas simples impedirão a avaliação. Aspas duplas serão avaliadas.

# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt

# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt

# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)

Você pode usar aspas simples dentro de aspas duplas e você pode usar aspas duplas dentro de aspas duplas, mas aspas duplas dentro de aspas simples não devem ser feitas (sem escapá-las) não serão avaliadas, elas serão interpretadas literalmente. Aspas simples dentro de aspas simples não devem ser feitas (sem escapá-las).

Você precisará obter um entendimento completo das cotações para usar o Bash com eficiência. Muito importante!

Como regra geral, eu não uso aspas se quiser que o Bash expanda algo em elementos (como uma matriz), uso aspas simples para cadeias de caracteres literais que não devem ser alteradas e faço uso liberal de aspas duplas para variáveis que provavelmente retornarão qualquer tipo de string. Isso é para garantir que espaços e caracteres especiais sejam preservados.

AsymLabs
fonte
Como você usaria aspas duplas dentro de aspas duplas ??? Isso é um erro de digitação? E por que eu deveria escapar aspas duplas dentro de aspas simples? Eu acho que você misturou as frases, talvez?
Byte Commander
@ByteCommander Sim, o conceito de aspas duplas colocado dentro de aspas duplas é usado com bastante frequência - veja este post para um exemplo de trabalho de destaque. Geralmente, isso é feito para proteger cadeias que contêm espaços, geralmente com relação às cadeias de caminho. As aspas duplas podem ser usadas em aspas simples com ou sem escape, mas serão interpretadas literalmente, ou seja, não levarão à avaliação. Vou esclarecer esse ponto no post.
AsymLabs 15/15