Muito novo no UNIX, mas não novo na programação. Usando o Terminal no MacBook. Para fins de gerenciamento e pesquisa de listas de palavras para a construção de palavras cruzadas, estou tentando me familiarizar com o comando Grep e suas variações. Parece bem direto, mas ficar desligado desde o início com o que pensei que deveria ser um caso simples.
Quando eu entro
grep "^COW" masternospaces.txt
Consigo o que quero: uma lista de todas as palavras que começam com COW.
Mas quando eu entro
grep "COW$" masternospaces.txt
Espero obter uma lista de palavras que terminam com COW (existem muitas dessas palavras) e nada é retornado.
O arquivo é um arquivo de texto sem formatação, com cada linha apenas uma palavra (ou uma frase da palavra sem espaços) em maiúsculas.
Alguma idéia do que poderia estar acontecendo aqui?
hexdump
para verificar exatamente como as terminações de sua linha estão formatadas. Eu sugiro que você use o meu formato favorito:hexdump -e '"%08_ad (0x%08_ax) "8/1 "%02x "" "8/1 "%02x "' -e '" "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
. Com a saída, verifique as terminações da linha:0a
->LF
,0d
->CR
.Respostas:
Como o @steeldriver mencionou, é provável que o problema seja causado por um estilo de final de linha diferente do que o
grep
esperado.Para verificar as terminações de linha
Você pode usar
hexdump
para verificar exatamente como as terminações de sua linha estão formatadas. Sugiro que você use meu formato favorito:Com a saída, verifique as terminações da linha:
0a
->LF
,0d
->CR
. Um exemplo muito rápido daria algo como isto:Nota os fins de linha no formato dos:
0d 0a
.Para alterar as terminações de linha
Você pode ver aqui ou aqui vários métodos para alterar as terminações de linha usando várias ferramentas, mas, como algo único, você sempre pode usar o vi / vim:
Para grep sem alterar nada
Se você quiser apenas
grep
corresponder, não importa o final da linha, sempre poderá especificar finais de linha como este:Se uma linha em branco for mostrada, você pode verificar se realmente correspondeu a algo usando a
-v
opção decat
:Meu favorito pessoal
Você também pode grep e padronizar a saída usando
sed
:onde
^M
é obtido digitandoCtrl-V Ctrl-M
no teclado.Espero que isto ajude!
fonte
[[:cntrl:]]
@ user43791 sugerido e ainda não está combinando nada para mim. Isso não faz sentido. Estou usando GNU grep 2.20 e analisar a saída de nDPI que foi gravado em um arquivo de textocat -v yourfile.ext
, o que vê?file
.Embora você possa usar a sintaxe RegEx 'padrão' com grep (como na resposta de @ user43791 ), o grep também tem outros identificadores para indicar os limites de entrada.
Os marcadores para o início e o fim de toda a linha são
\`
(backtick) (em vez de^
) e\'
(apóstrofo) (em vez de$
).Portanto, para o seu comando original, você usaria:
grep "COW\'" masternospaces.txt
Nota lateral: também é importante observar isso
?
e+
será tratado literalmente, a menos que você os escape usando\?
e\+
para torná-los equivalentes do seletor no estilo RegEx.Fonte:
grep
sintaxe da expressão regularfonte
Outra maneira de remover o
\r
antes do grep:Gosto que está muito claro, já que não me lembro de coisas assim
[[:cntrl:]]
por muito tempo.fonte
"COW $" quando o bash define o parâmetro para grep, foi interpretado como 'COW' onde trata "$" como "", pois $ é um símbolo de escape. quando nada foi associado a $, ele é interpretado como uma string vazia pelo shell bash; portanto, você deve usar grep 'COW $' masternospaces.txt.
fonte
$
, ele seria deixado sozinho pelo bash e usado pelo grep. Veja você mesmo:echo "COW$"
- o$
ainda estará lá.No BSD grep, você precisa escapar de "$" e colocar sua string entre aspas duplas:
fonte
$
item não será especial para o shell, porque o item a seguir não é um nome de variável de shell válido. Usar aspas simples em seqüências de caracteres estáticas é uma idéia melhor, mas não fará diferença aqui.