grep
parece quebrado na minha máquina. Reinstalá-lo não ajuda. Uma reinicialização não ajuda. As duas primeiras linhas criam um arquivo contendo texto arbitrário e a entrada é terminada com o caractere control-D.
ls -1
significa lista em uma coluna. Segue um exemplo...
> cat > file0.txt
asdf
> cp file0.txt file1.txt
> ls -1
file0.txt
file1.txt
> ls -1 | grep f*
>
Antes de experimentar esse problema, cometi um erro ao invocar o grep com uma cotação incomparável, mas não entendo como esse problema pode sobreviver a uma reinicialização.
Exemplo de cotação sem correspondência...
ls -1 | grep 'file* | wc
Neste exemplo, a listagem de diretórios é canalizada para grep, que canaliza para o programa contador de linha, palavra e byte wc
.
A expressão
grep f*
, no seu caso, será expandidagrep file0.txt file1.txt
pelo shell.Aparentemente não há nenhuma linha com
file0.txt
no arquivo file1.txt.Eu sei que não é isso que você queria, mas é assim que funciona.
grep
não usou a saída de dels
forma alguma.Quando você executa
grep f*
em uma situação em que seu shell se expandef*
para dois ou mais argumentos,grep
considera todos, exceto um deles, como nomes de arquivos a serem abertos e lidos. Quandogrep
lê de arquivos nomeados, seu comportamento padrão de leitura da entrada padrão não se aplica, portanto, ele não lê dados canalizados para ele de outro comando.Seu
grep
programa não está quebrado e o comportamento que você observou é o comportamento correto e esperado, e é por isso que a reinstalaçãogrep
e a reinicialização não o alteraram. Seguem detalhes.grep f*
não passou um argumento def*
para grep.grep
nunca vi o textof*
. Como diz Soren A ,f*
é um globo. Os globos são tratados especialmente pelo seu shell. Comof*
não foi citado , o shell o expandiu para os nomes dos arquivos no diretório atual que começam comf
. Cada um desses nomes foi passadogrep
como um argumento separado. ( Esse tipo de expansão de shell é conhecido como globbing, expansão de nome de arquivo e expansão de nome de caminho.)Com base na sua descrição, existem exatamente dois arquivos que correspondem ao
f*
glob:file0.txt
efile1.txt
. Como esses são os dois únicos arquivos no diretório atual cujos nomes começam comf
, os argumentos de linha de comando passados paragrep
execuçãogrep f*
são exatamente os mesmos que são passados para ele de execuçãogrep file0.txt file1.txt
. Se você adicionasse mais desses arquivos ao diretório,grep f*
passaria mais do que esses dois nomes de arquivo como argumentos paragrep
, masfile0.txt
aindafile1.txt
seria incluído entre eles.Você canalizou
ls
a saída paragrep
, masgrep
não leu do canal.Um pipe conecta a saída padrão de um comando à entrada padrão do outro. Like
cat
e muitos outros comandos,grep
aceita entrada de duas maneiras:Você pode passar nomes de arquivos como argumentos de linha de comando e ele lerá esses arquivos. O primeiro argumento não opcional
grep
é o padrão, mas os argumentos não opcionais subsequentes são tratados como nomes de arquivo dos quais a entrada será obtida.(Você não está tentando passar vários padrões para
grep
, mas se estivesse, poderia usar a-e
opção, cujo operando é sempre tratado como um padrão.)Você não pode passar argumentos de nome de arquivo e ele lerá de sua própria entrada padrão. Essa é a situação em que é eficaz canalizar para arquivos
grep
. É apenas na ausência de argumentos de nome de arquivo quegrep
lê a entrada padrão.É por isso que é possível usar
grep
para pesquisar um ou mais arquivos, sem bloquear e esperar que você insira a entrada em um terminal. Quando você canaliza paragrep
, a entrada extra que não faria sentidogrep
usar vem do comando no lado esquerdo do canal e não do seu terminal.grep
ainda não o usa, e isso é uma coisa boa.(Você não está tentando fazer
grep
com que leia a entrada padrão além de um ou mais arquivos nomeados, mas se estivesse, você poderia passar o-
argumento.)Como você tem dois arquivos no diretório atual cujos nomes começam com
f
, o globf*
se expande para dois argumentos. O primeiro,file0.txt
, é usado como padrão . O segundo,file1.txt
, é usado para nomear um arquivo de entrada. Comogrep
é fornecido um argumento especificando um arquivo de entrada, a primeira das duas situações descritas acima se aplica ("Você pode passar nomes de arquivos como argumentos de linha de comando"). Portanto,grep
nunca lê da entrada padrão e nunca usa a saída dols
.é má forma.
deve ser preferido.
Ao usar padrões regex mais complexos, alterne para
egrep
/grep -E
.Enquanto estou aqui,
cat
raramente é necessário.tac
é 100x mais útil do quecat
.cat
o abuso é um problema sério em sistemas do tipo Unix. ;)*
é um caractere especial que é interpretado livremente como um novo comando/instrução. Você quer colocar um\
na frente dele:No entanto, o que você provavelmente deseja é obter todos os arquivos começando com
f
em vez de TODOS os arquivos contendo umf
, então use outro caractere especial:O
^
grep instrui para encontrar linhas começando comf
.