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).
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).
Respostas:
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.
") 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).
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.
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 comofind . -name *.txtresultará em comportamento inesperado, se houver um arquivo txt no diretório atual. É melhor usar aspas neste caso.