Algo ao longo das linhas de:
find . -print -exec file {} \; | grep "PalmOS"
Para arrumar o canal de saída através do awk, adicionando:
| awk '{print substr($1,2,length($1)-2)}'
Existe um arquivo de comando bash (1) que produz o tipo de conteúdo de um arquivo de acordo com as definições de padrões correspondentes em / etc / magic e / usr / share / misc / magic.
Existe uma maneira de usar esses arquivos "mágicos" de definição de padrão como um teste para o comando "find"?
Por exemplo, existem alguns arquivos de texto e arquivos "PalmOS application"
file -b palmapp
PalmOS application
file -b readme.txt
ASCII text
Eu preciso de alguma forma de encontrar os arquivos que correspondem ao "aplicativo PalmOS" em vez de "texto ASCII", por exemplo, este é um comando ideal:
find . -magic "PalmOS*"
Existe alguma ideia para escrever um comando bash de linha única para cada teste?
Algo ao longo das linhas de:
find . -print -exec file {} \; | grep "PalmOS"
Para arrumar o canal de saída através do awk, adicionando:
| awk '{print substr($1,2,length($1)-2)}'
Não há recurso interno de find
para analisar o conteúdo do arquivo, mas é possível invocar file
. Usar o shell para combinar vários programas específicos de tarefas ( find
para percorrer árvores de diretórios, file
para analisar o conteúdo do arquivo) é a maneira Unix de fazer as coisas.
Você deseja atuar em arquivos para os quais a saída do comando file -b -- "$filename"
contenha a string PalmOS application
. Isso pode ser testado com o script de shell
case "$(file -b -- "$filename")" in *"PalmOS application"*) true;; *) false;; esac
Você pode usar esse script em um comando find
da seguinte forma:
find . -type f -exec sh -c 'case "$(file -b "$0")" in *"PalmOS application"*) true;; *) false;; esac' {} \; -print
Substitua -print
pela ação que você deseja executar (que pode ser outro -exec …
). Essa segunda ação é executada apenas se a ação anterior for verdadeira, que é quando o comando shell retorna 0 (ou seja, true).
Como alternativa, em zsh, você pode permitir que o shell faça a travessia do diretório com o **
glob . O .
qualificador de glob restringe as correspondências a arquivos regulares (como -type f
para find
).
for x in **/*(.); do
[[ $(file -b -- $x) = *"PalmOS application"* ]] || continue
…
done
No bash ≥4.3, você pode usar **
para globalização recursiva, mas é necessário ativar a opção globstar
primeiro. No bash 4.0–4.2, globstar
já está disponível, mas tenha em atenção que **
percorre links simbólicos para diretórios. No ksh93, use set -o globstar
em vez de shopt -s globstar
.
shopt -s globstar
for x in **/*; do
[[ -f $x ]] || continue
[[ $(file -b -- "$x") = *"PalmOS application"* ]] || continue
…
done
Se os nomes dos arquivos não contiverem espaço em branco ou :\"'
, um método alternativo será executar file
nos nomes dos arquivos e analisar a saída.
find -type f |
xargs file |
sed -n 's/:.*PalmOS application.*//p' |
xargs somecommand
Se os nomes dos seus arquivos contiverem espaço em branco, mas não houver novas linhas ou vírgulas, você poderá usar o shell para fazer a análise.
find -type f |
while IFS=: read -r filename type; do
case "$type" in
*"PalmOS application"*)
…;;
esac
done
Isso não usa find
, mas a configuração pattern
e directory
produzirá os resultados solicitados pela sua pergunta:
pattern="PalmOS application"
directory=.
for f in $directory/*; do
if [[ $(file -b $f) == "$pattern" ]]; then
echo $f;
fi;
done
Tags find file-command