Como extrair uma lista de índices separada por vírgula de todos os arquivos ausentes dentro de um diretório?

0

Atualmente, tenho um diretório /mydir e, dentro, devem estar 1.000 arquivos de dados no formato File1.exe, File2.exe, ... , File100.exe .

Eu tenho atualmente um loop for que procura e exibe quais arquivos estão faltando:

for((i=1; i<=1000; i++))
do 
    name="File.${i}.exe"; [[ ! -e "$name" ]] && echo "$i" 
done

Eu estou querendo saber se existe alguma maneira de, em vez de repetir o índice ausente, colocá-lo em uma lista separada por vírgulas, como:

1,5,20,40,etc .

Existe uma maneira de fazer isso?

    
por user321627 25.06.2018 / 12:20

3 respostas

3

Use apenas, para uma string separada por vírgula, continue adicionando o índice de arquivos a uma variável e imprima a variável

for((i=1; i<=30; i++))
do
    name="File${i}.exe"; [[ ! -e "$name" ]] && files="$files$i,"
done
echo $files | sed  s/,$//

Ou você pode armazenar os valores em uma matriz / lista

arr=()
for((i=1; i<=30; i++))
do
    name="File${i}.exe"; [[ ! -e "$name" ]] && arr+=($i)
done
(IFS=, ; echo "${arr[*]}") #to print the array with comma as separator 
    
por 25.06.2018 / 12:33
2

Usando /bin/sh e a lista de parâmetros posicionais para armazenar os nomes dos arquivos ausentes:

set --
i=1
while [ "$i" -le 1000 ]; do
    name="File.$i.exe"
    [[ ! -e "$name" ]] && set -- "$@" "$name"
    i=$(( i + 1 ))
done

( IFS=','; printf 'Missing files: %s\n' "$*" )

ou usando bash e uma matriz:

missing=()
for (( i=1; i<=1000; ++i )); do
    name="File.$i.exe"
    [[ ! -e "$name" ]] && missing+=( "$name" )
done

( IFS=','; printf 'Missing files: %s\n' "${missing[*]}" )

Ao usar "$*" ou "${missing[*]}" , a matriz será convertida em uma string. A string será unida ao primeiro caractere de $IFS como o delimitador (por padrão, um espaço). A subshell define IFS para uma vírgula e, em seguida, imprime a matriz unida em vírgulas. O subshell impede que a variável IFS seja definida no restante do script.

O código também seria capaz de lidar com nomes de arquivos contendo espaços, etc.

    
por 25.06.2018 / 12:46
1

Use a ferramenta paste , apenas adicione | paste -sd, ao loop:

for((i=1; i<=1000; i++))
do 
    name="File.${i}.exe"; [[ ! -e "$name" ]] && echo "$i" 
done | paste -sd,

Explicação:

paste - merge lines of files
paste [OPTION]... [FILE]...
With no FILE, or when FILE is -, read standard input.

  • -s : cole um arquivo de cada vez, em vez de em paralelo
  • -d : delimiter ( , neste caso)
por 25.06.2018 / 15:45