find . | grep user
e find . -path "user*"
fazem duas coisas bem diferentes. Eles podem parecer que são iguais, mas não são.
Vou mencionar as duas diferenças mais óbvias primeiro apenas para tirá-las do caminho. A primeira é que você precisa usar -path '*user*'
para obter exatamente o mesmo resultado que o grep user
. Isso não é muito importante. A segunda diferença óbvia, um pouco mais importante, é que a execução de dois processos, quando um é feito, é inerentemente menos eficiente (em termos de uso de CPU e RAM) - uma eficiência mais significativa do que salvar dois pressionamentos de teclas.
A verdadeira diferença, no entanto, é o que você pode fazer facilmente com os nomes de arquivos encontrados pelo find
em si, e aqueles encontrados usando grep
. Como a maioria dos utilitários de linha de comando no linux / unix, o find
é uma ferramenta muito flexível - ele é capaz de muito mais do que apenas localizar arquivos e imprimir seus nomes de arquivos.
Com o pipe para grep, você tem apenas uma lista de nomes de arquivos que correspondem a um padrão específico.
Se você usou o caractere A NUL como separador de nome de arquivo, em vez de apenas uma nova linha (wg com -print0
action e% GNU grep
-z
aka --null-data
), é possível canalizá-lo com segurança em xargs -0
(ou perl
ou awk
ou qualquer outro programa que possa receber entrada separada por NUL) e processar os arquivos.
por exemplo. usando du -sch
como um exemplo muito simples:
find . -print0 | grep -z user | xargs -0r du -sch --
Se você não fez isso, ou se a sua versão de grep
não suporta -z
, então você só pode processar seus nomes de arquivos com segurança se a) usar uma nova linha como separador de nome de arquivo eb) estiver absolutamente certeza de que nenhum dos nomes de arquivo conterá uma nova linha (novas linhas são válidas em nomes de arquivos - irritantes, mas verdadeiras, e algo com o que você ocasionalmente tem que lidar).
find . | grep user | xargs -d '\n' -r du -sch --
Ambos usam 4 processos (find, grep, xargs e du) em um pipeline para o uso total do disco dos nomes de arquivos.
Com find
, no entanto, você pode usar as opções -exec
ou -execdir
para processar diretamente o nome do arquivo sem precisar se preocupar com o delimitador que está usando.
por exemplo,
find . -path '*user*' -exec du -sch -- {} +
Isso usa 2 processos (find e du) para obter o mesmo resultado.
A segunda diferença real (e essa é grande) é que, enquanto grep
só pode selecionar arquivos combinando um padrão regex com o nome de cada arquivo, find
pode usar os metadados de cada arquivo para filtrar correspondências indesejadas (ou para selecionar apenas correspondências muito específicas - mesma coisa)
Alguns exemplos de quais find
são capazes de:
Se você quiser apenas arquivos regulares, use -type f
, se quiser apenas diretórios, use -type d
, symlinks -type l
e assim por diante.
Se você deseja apenas arquivos pertencentes a um usuário específico, use -uid nnn
ou -user username
. mesmo para -gid nnn
e -group groupname
.
find
pode corresponder a permissões, timestamps, tamanho e se um arquivo é -readable
ou -writable
pelo usuário que o executa.
Ele também incorporou a correspondência de expressão regular ( -regex
, com a opção de estilos de regex usando -regextype
), bem como a correspondência de glob ( -name
, -path
).
Você pode usar -prune
para excluir árvores inteiras de subdiretórios da pesquisa (reduzindo a quantidade de i / o do disco e o tempo necessário).
Ele pode combinar tudo isso com operadores de lógica booleana AND, OR e NOT.
find
também possui várias ações incorporadas. O padrão é -print
e já mencionei -print0
. Ele também pode exibir qualquer um dos metadados disponíveis de um arquivo no formato que você quiser com sua ação -printf
. Ele pode excluir arquivos com -delete
ou exibir uma lista detalhada (semelhante a ls -l
) com -ls
.
-exec
executa qualquer processo externo e fornece a lista de arquivos correspondentes na linha de comando com {}
. Um arquivo por vez, se você terminar o comando -exec
com \;
ou quantos couberem em uma linha de comando do shell por vez com +
.
-execdir
faz o mesmo, mas, se estiver usando \;
, muda para o diretório de cada arquivo antes de executar o processo externo. Com +
, ele é alterado para o diretório e, em seguida, executa o comando externo com tantos argumentos de nome de arquivo que caberão em uma linha de comando.
BTW, alguns dos predicados e ações predicados acima são extensões GNU, e podem não funcionar em outras versões não-GNU de find
.