Liste qualquer arquivo terminado com .in e correspondente .out com script shell

4

Eu tenho um diretório cheio de arquivos que terminam com extensões diferentes, como eu poderia listar / selecionar apenas os arquivos que terminam em .in e .out que compartilham o mesmo nome de base?

por exemplo,

file1.txt
file1.in
file2.in
file3.in
file2.out
file3.out

O que eu quero selecionar desses arquivos é:

file2.in
file2.out
file3.in
file3.out
    
por Locke McDonnell 26.11.2012 / 03:06

4 respostas

5

Como você deseja que .in seja emparelhado com .out , percorra apenas *.in e verifique se existe um arquivo .out correspondente, se for o caso, imprima ambos:

for f in *.in; do
  if [[ -f ${f%.in}.out ]]; then
    echo $f
    echo ${f%.in}.out
  fi
done
    
por 26.11.2012 / 14:22
3

Primeiro jogo contra todos os arquivos, e verifique se existe o arquivo .out, em seguida, imprima o nome:

for x in *; do
   if [[ "$x" =~ ^(.*)\.in ]] && [[ -f ${BASH_REMATCH[1]}.out ]];then 
      echo -n "$x ${x%%.in}.out "; 
   fi
done
echo
    
por 26.11.2012 / 03:11
2

Com zsh:

has_out() [[ -e $REPLY:r.out ]]
ls -ld -- *.in(+has_out)
    
por 26.11.2012 / 18:19
1

Você pode listar todos esses arquivos, remover as extensões, filtrar duplicatas e imprimi-las:

$ ls | grep '\(\.in\|.out\)$' | sed 's/....$//' \
     | sort | uniq -c | grep '^[\t ]*2' | sed 's/^[\t ]\+2 //'

Vantagens:

  • não precisa de bash
  • faz apenas uma operação cara - lista de diretórios - isto é, não precisa stat (2) cada arquivo ( como em [[ -f ... ]] )

Caso o ls já classifique alfabeticamente sua saída, o comando sort poderá ser removido do canal. Não sei se o POSIX especifica o comportamento de classificação de um ls .

O canal imprime todos os nomes básicos se os arquivos com .in e .out extensão.

Se, então, precisar de uma lista dos arquivos correspondentes, você terá que sufixar a lista com as extensões filtradas anteriormente. Por exemplo, assim:

$ ls | grep '\(\.in\|.out\)$' | sed 's/....$//' \
     | sort | uniq -c | grep '^[\t ]*2' \
     | sed -e 's/^[\t ]\+2 //' -e 's/$/.in/ ; p; s/in$/out/'
    
por 26.11.2012 / 10:06