Imprime arquivos inexistentes de uma entrada de pipe

5

Eu tenho um diretório com muitos arquivos .PDF e .JPG .

Deve haver um arquivo .JPG para cada .PDF com o mesmo nome.
Estou tentando usar um comando para encontrar .PDF arquivos que não possuem um arquivo .JPG .

Meu comando atual é:

find -iname '*.jpg' -print0|sed 's/jpg$/pdf$/ig' |xargs -0 ls

Isso imprime : No such file or directory de erro em arquivos não existentes;
o problema é que os erros de ls não podem ser manipulados por grep ou sed .
Qualquer um desses resolve meu problema:

  • Como posso fazer com que ls apenas liste arquivos que não existem?
  • Como tratar / filtrar erros de ls com sed / grep ?
  • qualquer outra forma de verificação de existência de arquivo (sem criar arquivos de script bash)?
por RYN 26.12.2012 / 23:59

5 respostas

2

Eu acho que você deveria estar usando um loop

IFR=$'
IFR=$'%pre%' # because you use -print0 on your find
for jpg_file in 'find -iname '*.jpg' -print0'
do
  pdf_file='echo "$jpg_file" | sed 's/jpg$/pdf/i''
  if [ -e "$pdf_file" ]; then
    echo "$pdf_file exist"
  else
    echo "$pdf_file missing"
  fi
done
' # because you use -print0 on your find for jpg_file in 'find -iname '*.jpg' -print0' do pdf_file='echo "$jpg_file" | sed 's/jpg$/pdf/i'' if [ -e "$pdf_file" ]; then echo "$pdf_file exist" else echo "$pdf_file missing" fi done
    
por 27.12.2012 / 00:21
2

POSIXly, você poderia fazer:

find . -name '*.[jJ][pP][gG]' -exec sh -c '
  for i do
    [ -e "${i%.*}.pdf" ] || printf "%s\n" "$i"
  done' sh {} +

Se você quiser pesquisar arquivos PDF sem distinção entre maiúsculas e minúsculas, faça o seguinte:

find . -name '*.[jJ][pP][gG]' -exec sh -c '
  for i do
    set -- "${i%.*}".[pP][dD][fF]
    case $1 in
      (*"]") printf "%s\n" "$i"
    esac
  done' sh {} +
    
por 27.12.2012 / 11:52
2

Com zsh,

setopt extendedglob
print -rl -- **/*.(#i)jpg(e{'[[ ! -e $REPLY:r.pdf ]]'})

Informaria os arquivos jpg que não têm um arquivo pdf correspondente.

Se você quiser considerar os arquivos PDF e PdF :

print -rl -- **/*.(#i)jpg(e{'f=($REPLY:r.(#i)pdf(N)); ((!$#f))'})

Claro que, em vez de imprimi-los, você passa por cima deles como:

for f (**/...) convert $f $f:r.pdf

:r fornece o nome raiz (sem a extensão) de um nome de arquivo ( csh heritage), (#i) ativa a globalização sem distinção entre maiúsculas e minúsculas (quando extendedglob está ativado ), O e{some code} globbing qualifier é executar some code para determinar se um arquivo deve ser globbed ou não.

Observe que ele ignoraria arquivos ocultos (aqueles cujo nome começa com um ponto). Adicione o qualificador de globbing D para adicioná-los novamente.

    
por 27.12.2012 / 09:40
1

Isso deve ajudá-lo:

find . -iname '*.pdf' -exec bash -c '[[ -f $(echo $(echo {}|sed "s/pdf/jpg/")) ]] || echo $(echo {}|sed "s/pdf/jpg/") not found' \;

Arquivos PDF que não possuem arquivos JPG correspondentes serão reproduzidos.

    
por 27.12.2012 / 05:10
1

Aqui eu tenho o seguinte diretório de amostra.

a1.jpg
a1.pdf
a2.jpg
a2.pdf
a3.pdf
a4.pdf

Este comando imprimirá um 2 para cada arquivo PDF que tenha um arquivo JPG correspondente e um 1 para PDFs que não tenham.

% find . -type f|sed 's/pdf\|jpg//'|sort|uniq -c|sed 's/$/pdf/'
  2 ./a1.pdf
  2 ./a2.pdf
  1 ./a3.pdf
  1 ./a4.pdf

Usando o 1 e 2 na saída, você pode grep para qualquer um e enviar isso para xargs ou o que você quiser.

Por exemplo:

Lista de arquivos com JPG .

% find . -type f|sed 's/pdf\|jpg//'|sort|uniq -c|sed 's/$/pdf/' |grep " 1 "|awk 
'{print $2}'
./a3.pdf
./a4.pdf

Lista de arquivos que não têm JPG .

% find . -type f|sed 's/pdf\|jpg//'|sort|uniq -c|sed 's/$/pdf/' |grep " 2 "|awk '{print $2}'
./a1.pdf
./a2.pdf

passando-os para xargs ls .

% find . -type f|sed 's/pdf\|jpg//'|sort|uniq -c|sed 's/$/pdf/' |grep " 2 "|awk '{print $2}'|xargs ls
./a1.pdf  ./a2.pdf

passando-os para xargs ls -l .

% find . -type f|sed 's/pdf\|jpg//'|sort|uniq -c|sed 's/$/pdf/' |grep " 2 "|awk '{print $2}'|xargs ls -l
-rw-rw-r-- 1 saml saml 0 Dec 27 00:14 ./a1.pdf
-rw-rw-r-- 1 saml saml 0 Dec 27 00:14 ./a2.pdf
    
por 27.12.2012 / 06:27