AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 778828
Accepted
Terry
Terry
Asked: 2024-06-23 05:49:46 +0800 CST2024-06-23 05:49:46 +0800 CST 2024-06-23 05:49:46 +0800 CST

incrementando nomes de arquivos em zsh

  • 772

Estou tentando escrever um script em zsh (Linux Mint 21.3 "Virginia") para mover (ou copiar) um arquivo de $source para $target com resultados confusos. Estou usando caixas de diálogo de arquivo yad para selecionar os arquivos e nomear o diretório de destino. O melhor que consegui fazer foi copiar apenas a escolha final para o destino vazio.

Aqui está o roteiro completo


setopt -x
setopt -v
autoload -Uz zmv

# WARNING Just because two or more files from different sources have identical names does not mean 
#that the files are identical.


declare -a array
array=$(yad --width=600 --height=800 \
--title="Choose files to move." \
--file --multiple --separator='\n') 
echo $array

target=$(yad --width=600 --height=800 \
--title="Choose destination." \
--file --directory)
echo "target="$target

# The file you wish to move may already exist in the target directory. 
# If you do not want to overwrite it you can use
# mv -n
# mv --no-clobber
# or 
# mv --backup=numbered
# Clumsy, but better than nothing, and doesn't give me what I want.
# That is why I wrote this script, it adds an incremented number to the name.
# eg <movie>.<ext>
# eg <movie>_copy1.<ext>
# eg <movie>_copy2.<ext>
# Yes, I could use brackets but they are illegal characters and I have a renamer
# that would remove them.

# You can't just use <filename>.$ext to check if the file exists in target because
# you'll miss any existing copies. You have to account for iteration.
for filename in $array; do
unset x
# decompose filename
# just name without path 
filename=$filename:t
echo
echo
echo "filename="$filename
echo
echo
# name without extension
shortname=${filename%.*}
echo "shortname="$shortname
echo
echo
# extension
ext=${filename##*.}
echo
echo
echo "ext="$ext

# The key here is to rename the file (if necessary) BEFORE copying it to target instead 
# of after.
#   Does file already exist in $target? Count them.
x=$(find $target -iname "$shortname*.$ext" | wc -c)
echo
echo
echo "x="$x

# If no file exists, move to target.
# If one file exists then $x will return "1". Think of it as
# <filename>_copy0.<ext>,
# this makes the file you wish to move
# <filename>_copy1.<ext>, - the value of $x.

case $x in
    0) cp $filename $target
    sleep .2
    ;;
    *) mv $filename $shortname_copy$x.$ext
    cp $filename $target
    sleep .2
    ;;
esac
    done
    exit 0

Aqui está a saída do terminal de duas execuções do script usando os mesmos parâmetros.

+/home/revision-6/bin/cpi:4> setopt -v
autoload -Uz zmv
+/home/revision-6/bin/cpi:5> autoload -Uz zmv

# WARNING Just because two or more files from different sources have identical names does not mean 
#that the files are identical.


declare -a array
+/home/revision-6/bin/cpi:11> declare -a array
array=$(yad --width=600 --height=800 \
--title="Choose files to move." \
--file --multiple --separator='\n') 
+/home/revision-6/bin/cpi:12> array=+/home/revision-6/bin/cpi:12> yad '--width=600' '--height=800' '--title=Choose files to move.' --file --multiple '--separator=\n'

(yad:3962282): dbind-WARNING **: 15:34:42.076: Couldn't connect to accessibility bus: Failed to connect to socket /root/.cache/at-spi/bus_0.0: Permission denied
+/home/revision-6/bin/cpi:12> array=$'/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv\n/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv\n/home/revision-6/Videos/betty_boop_more_pep_1936.mkv' 
echo $array
+/home/revision-6/bin/cpi:15> echo $'/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv\n/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv\n/home/revision-6/Videos/betty_boop_more_pep_1936.mkv'
/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv
/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv
/home/revision-6/Videos/betty_boop_more_pep_1936.mkv

target=$(yad --width=600 --height=800 \
--title="Choose destination." \
--file --directory)
+/home/revision-6/bin/cpi:17> target=+/home/revision-6/bin/cpi:17> yad '--width=600' '--height=800' '--title=Choose destination.' --file --directory

(yad:3962312): dbind-WARNING **: 15:34:54.949: Couldn't connect to accessibility bus: Failed to connect to socket /root/.cache/at-spi/bus_0.0: Permission denied
+/home/revision-6/bin/cpi:17> target=/home/revision-6/video_processing 
echo "target="$target
+/home/revision-6/bin/cpi:20> echo 'target=/home/revision-6/video_processing'
target=/home/revision-6/video_processing

# The file you wish to move may already exist in the target directory. 
# If you do not want to overwrite it you can use
# mv -n
# mv --no-clobber
# or 
# mv --backup=numbered
# Clumsy, but better than nothing, and doesn't give me what I want.
# That is why I wrote this script, it adds an incremented number to the name.
# eg <movie>.<ext>
# eg <movie>_copy1.<ext>
# eg <movie>_copy2.<ext>
# Yes, I could use brackets but they are illegal characters and I have a renamer
# that would remove them.

# You can't just use <filename>.$ext to check if the file exists in target because
# you'll miss any existing copies. You have to account for iteration.
for filename in $array; do
unset x
# decompose filename
# just name without path 
filename=$filename:t
echo
echo
echo "filename="$filename
echo
echo
# name without extension
shortname=${filename%.*}
echo "shortname="$shortname
echo
echo
# extension
ext=${filename##*.}
echo
echo
echo "ext="$ext

# The key here is to rename the file (if necessary) BEFORE copying it to target instead 
# of after.
#   Does file already exist in $target? Count them.
x=$(find $target -iname "$shortname*.$ext" | wc -c)
echo
echo
echo "x="$x

# If no file exists, move to target.
# If one file exists then $x will return "1". Think of it as
# <filename>_copy0.<ext>,
# this makes the file you wish to move
# <filename>_copy1.<ext>, - the value of $x.

case $x in
    0) cp $filename $target
    sleep .2
    ;;
    *) mv $filename $shortname_copy$x.$ext
    cp $filename $target
    sleep .2
    ;;
esac
    done
+/home/revision-6/bin/cpi:38> filename=/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv
/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv
/home/revision-6/Videos/betty_boop_more_pep_1936.mkv
+/home/revision-6/bin/cpi:39> unset x
+/home/revision-6/bin/cpi:42> filename=betty_boop_more_pep_1936.mkv 
+/home/revision-6/bin/cpi:43> echo

+/home/revision-6/bin/cpi:44> echo

+/home/revision-6/bin/cpi:45> echo 'filename=betty_boop_more_pep_1936.mkv'
filename=betty_boop_more_pep_1936.mkv
+/home/revision-6/bin/cpi:46> echo

+/home/revision-6/bin/cpi:47> echo

+/home/revision-6/bin/cpi:49> shortname=betty_boop_more_pep_1936 
+/home/revision-6/bin/cpi:50> echo 'shortname=betty_boop_more_pep_1936'
shortname=betty_boop_more_pep_1936
+/home/revision-6/bin/cpi:51> echo

+/home/revision-6/bin/cpi:52> echo

+/home/revision-6/bin/cpi:54> ext=mkv 
+/home/revision-6/bin/cpi:55> echo

+/home/revision-6/bin/cpi:56> echo

+/home/revision-6/bin/cpi:57> echo 'ext=mkv'
ext=mkv
+/home/revision-6/bin/cpi:62> x=+/home/revision-6/bin/cpi:62> find /home/revision-6/video_processing -iname 'betty_boop_more_pep_1936*.mkv'
+/home/revision-6/bin/cpi:62> x=+/home/revision-6/bin/cpi:62> wc -c
+/home/revision-6/bin/cpi:62> x=0 
+/home/revision-6/bin/cpi:63> echo

+/home/revision-6/bin/cpi:64> echo

+/home/revision-6/bin/cpi:65> echo 'x=0'
x=0
+/home/revision-6/bin/cpi:73> case 0 (0)
+/home/revision-6/bin/cpi:74> cp betty_boop_more_pep_1936.mkv /home/revision-6/video_processing
+/home/revision-6/bin/cpi:75> sleep .2
    exit 0
+/home/revision-6/bin/cpi:83> exit 0
revision-6@revision6-NYI3 ~/Videos
 % cpi
+/home/revision-6/bin/cpi:4> setopt -v
autoload -Uz zmv
+/home/revision-6/bin/cpi:5> autoload -Uz zmv

# WARNING Just because two or more files from different sources have identical names does not mean 
#that the files are identical.


declare -a array
+/home/revision-6/bin/cpi:11> declare -a array
array=$(yad --width=600 --height=800 \
--title="Choose files to move." \
--file --multiple --separator='\n') 
+/home/revision-6/bin/cpi:12> array=+/home/revision-6/bin/cpi:12> yad '--width=600' '--height=800' '--title=Choose files to move.' --file --multiple '--separator=\n'

(yad:3962420): dbind-WARNING **: 15:35:35.029: Couldn't connect to accessibility bus: Failed to connect to socket /root/.cache/at-spi/bus_0.0: Permission denied
+/home/revision-6/bin/cpi:12> array=$'/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv\n/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv\n/home/revision-6/Videos/betty_boop_more_pep_1936.mkv' 
echo $array
+/home/revision-6/bin/cpi:15> echo $'/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv\n/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv\n/home/revision-6/Videos/betty_boop_more_pep_1936.mkv'
/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv
/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv
/home/revision-6/Videos/betty_boop_more_pep_1936.mkv

target=$(yad --width=600 --height=800 \
--title="Choose destination." \
--file --directory)
+/home/revision-6/bin/cpi:17> target=+/home/revision-6/bin/cpi:17> yad '--width=600' '--height=800' '--title=Choose destination.' --file --directory

(yad:3962450): dbind-WARNING **: 15:35:43.654: Couldn't connect to accessibility bus: Failed to connect to socket /root/.cache/at-spi/bus_0.0: Permission denied
+/home/revision-6/bin/cpi:17> target=/home/revision-6/video_processing 
echo "target="$target
+/home/revision-6/bin/cpi:20> echo 'target=/home/revision-6/video_processing'
target=/home/revision-6/video_processing

# The file you wish to move may already exist in the target directory. 
# If you do not want to overwrite it you can use
# mv -n
# mv --no-clobber
# or 
# mv --backup=numbered
# Clumsy, but better than nothing, and doesn't give me what I want.
# That is why I wrote this script, it adds an incremented number to the name.
# eg <movie>.<ext>
# eg <movie>_copy1.<ext>
# eg <movie>_copy2.<ext>
# Yes, I could use brackets but they are illegal characters and I have a renamer
# that would remove them.

# You can't just use <filename>.$ext to check if the file exists in target because
# you'll miss any existing copies. You have to account for iteration.
for filename in $array; do
unset x
# decompose filename
# just name without path 
filename=$filename:t
echo
echo
echo "filename="$filename
echo
echo
# name without extension
shortname=${filename%.*}
echo "shortname="$shortname
echo
echo
# extension
ext=${filename##*.}
echo
echo
echo "ext="$ext

# The key here is to rename the file (if necessary) BEFORE copying it to target instead 
# of after.
#   Does file already exist in $target? Count them.
x=$(find $target -iname "$shortname*.$ext" | wc -c)
echo
echo
echo "x="$x

# If no file exists, move to target.
# If one file exists then $x will return "1". Think of it as
# <filename>_copy0.<ext>,
# this makes the file you wish to move
# <filename>_copy1.<ext>, - the value of $x.

case $x in
    0) cp $filename $target
    sleep .2
    ;;
    *) mv $filename $shortname_copy$x.$ext
    cp $filename $target
    sleep .2
    ;;
esac
    done
+/home/revision-6/bin/cpi:38> filename=/home/revision-6/Videos/betty_boop_a_song_a_day_1936.mkv
/home/revision-6/Videos/betty_boop_is_my_palm_read_1932.mkv
/home/revision-6/Videos/betty_boop_more_pep_1936.mkv
+/home/revision-6/bin/cpi:39> unset x
+/home/revision-6/bin/cpi:42> filename=betty_boop_more_pep_1936.mkv 
+/home/revision-6/bin/cpi:43> echo

+/home/revision-6/bin/cpi:44> echo

+/home/revision-6/bin/cpi:45> echo 'filename=betty_boop_more_pep_1936.mkv'
filename=betty_boop_more_pep_1936.mkv
+/home/revision-6/bin/cpi:46> echo

+/home/revision-6/bin/cpi:47> echo

+/home/revision-6/bin/cpi:49> shortname=betty_boop_more_pep_1936 
+/home/revision-6/bin/cpi:50> echo 'shortname=betty_boop_more_pep_1936'
shortname=betty_boop_more_pep_1936
+/home/revision-6/bin/cpi:51> echo

+/home/revision-6/bin/cpi:52> echo

+/home/revision-6/bin/cpi:54> ext=mkv 
+/home/revision-6/bin/cpi:55> echo

+/home/revision-6/bin/cpi:56> echo

+/home/revision-6/bin/cpi:57> echo 'ext=mkv'
ext=mkv
+/home/revision-6/bin/cpi:62> x=+/home/revision-6/bin/cpi:62> find /home/revision-6/video_processing -iname 'betty_boop_more_pep_1936*.mkv'
+/home/revision-6/bin/cpi:62> x=+/home/revision-6/bin/cpi:62> wc -c
+/home/revision-6/bin/cpi:62> x=63 
+/home/revision-6/bin/cpi:63> echo

+/home/revision-6/bin/cpi:64> echo

+/home/revision-6/bin/cpi:65> echo 'x=63'
x=63
+/home/revision-6/bin/cpi:73> case 63 (0)
+/home/revision-6/bin/cpi:73> case 63 (*)
+/home/revision-6/bin/cpi:77> mv betty_boop_more_pep_1936.mkv 63.mkv
+/home/revision-6/bin/cpi:78> cp betty_boop_more_pep_1936.mkv /home/revision-6/video_processing
cp: cannot stat 'betty_boop_more_pep_1936.mkv': No such file or directory
+/home/revision-6/bin/cpi:79> sleep .2
    exit 0
+/home/revision-6/bin/cpi:83> exit 0

Para mim a lógica parece válida. Conte o número de iterações no destino e renomeie o arquivo ANTES de movê-lo, mas acho que meu shell-scripting-fu não está à altura da tarefa. Qualquer ajuda é bem vinda.

linux
  • 1 1 respostas
  • 78 Views

1 respostas

  • Voted
  1. Best Answer
    Gairfowl
    2024-06-23T21:33:48+08:002024-06-23T21:33:48+08:00

    Isso pode ser mais fácil com zsha poderosa sintaxe globalfind em vez de e wc. Experimente isto:

    #!/usr/bin/env zsh
    setopt extendedglob
    
    nextFilename() {
        local fqp=${1:?}
        local -a fileCopies=( ${fqp:r}(_copy<->|).${fqp:e}(#qNn) )
        local latestCopy=${fileCopies[-1]}
    
        if [[ -z $latestCopy ]]; then
            # no matching files at destination, use original filename
            print -r -- $fqp
        elif [[ $latestCopy == (#b)(*)_copy(<->)(.${fqp:e}) ]]; then
            # matching filename with _copyN, add one to number
            print -r -- ${match[1]}_copy$((${match[2]}+1))${match[3]}
        else
            # only has filename without a copy number, use _copy1
            print -r -- ${fqp:r}_copy1.${fqp:e}
        fi
    }
    

    A declaração principal é esta:

    local -a fileCopies=( ${fqp:r}(_copy<->|).${fqp:e}(#qNn) )
    

    Ele cria uma matriz classificada de nomes de arquivos do diretório de destino que corresponde ao padrão baseado no nome do arquivo de origem.

    • ${fqp:r}- a raiz do caminho do arquivo. Contém o diretório e a parte inicial do nome, ou seja, tudo menos a extensão.
    • (_copy<->|)- _copyN, ou nada (por exemplo, fname.extou fname_copy14.ext). <->é um padrão glob para qualquer número.
    • ${fqp:e}- a extensão do nome do arquivo.
    • (#qNn)- um conjunto de qualificadores globais que modificam o comportamento
      • #q- indica que esta expressão entre parênteses contém qualificadores glob.
      • N- permitir glob nulo, para que zero correspondências não sejam um erro.
      • n- ative NUMERIC_GLOB_SUBST para esta expansão, para que os resultados sejam ordenados numericamente. Com esta opção, um conjunto de nomes como f1 f11 f2será classificado como f1 f2 f11. Nomes de arquivos sem dígitos no mesmo lugar, como fname.exte fname_copy1.extainda serão classificados lexicalmente, mas aqui essa é a ordem que queremos, portanto, nenhum tratamento especial é necessário.

    Com o array classificado, o último valor do array (index -1) será o nome do arquivo com o número mais alto, então podemos usar isso para determinar o que deve acontecer a seguir. Uma vantagem de usar essa técnica é que ela pode lidar com lacunas na numeração; um algoritmo baseado em contagem pode ser prejudicado por isso.

    Usando/testando:

    >> destDir=./dest
    >> ls -l $destDir/*
    -rw-r--r--  1 me  staff  0 Jun 23 07:40 ./dest/filename.txt
    -rw-r--r--  1 me  staff  0 Jun 23 07:40 ./dest/filename_copy1.txt
    -rw-r--r--  1 me  staff  0 Jun 23 07:40 ./dest/filename_copy11.txt
    -rw-r--r--  1 me  staff  0 Jun 23 07:40 ./dest/filename_copy2.txt
    -rw-r--r--  1 me  staff  0 Jun 23 07:40 ./dest/onefile.txt
    
    >> srcFile=./src/filename.txt
    >> cp -v $srcFile $(nextFilename $destDir/${srcFile:t})
    ./src/filename.txt -> ./dest/filename_copy12.txt
    
    >> srcFile=./src/nodestfile.txt
    >> cp -v $srcFile $(nextFilename $destDir/${srcFile:t})
    ./src/nodestfile.txt -> ./dest/nodestfile.txt
    
    >> srcFile=onefile.txt
    >> cp -v $srcFile $(nextFilename $destDir/${srcFile:t})
    ./src/onefile.txt -> ./dest/onefile_copy1.txt
    

    Podemos usar esta função para construir um script que percorre uma matriz de nomes de arquivos:

    #!/usr/bin/env zsh
    setopt extendedglob
    
    #####
    local sourceFilePattern='~/src/*.mp4'
    vared -eh -p "Source Filename or Pattern > " sourceFilePattern
    if ((${ret::=$?})); then
        print "vared returned $ret; exiting ..."
        exit 1
    fi
    # expand the pattern
    local -a sourceFilenames=( ${~sourceFilePattern} )
    
    #####
    local destDir='~/dest'
    vared -eh -p "Target directory > " destDir
    if ((${ret::=$?})); then
        print "vared returned $ret; exiting ..."
        exit 1
    fi
    # expand '~', '*', etc.
    local -a destDirArray=( ${~destDir} )
    if ((${#destDirArray} > 1)); then
        print "Found more than one match for directory pattern $destDir"
        print "exiting ..."
        exit 1
    fi
    destDir=${destDirArray[1]}
    if [[ ! -d $destDir ]]; then
        print "Target $destDir does not exist or is not a directory."
        print "exiting ..."
        exit 1
    fi
    
    #####
    print
    print "Source file pattern: ${sourceFilePattern}"
    print "Source file count:   ${#sourceFilenames}"
    print "Destination:         ${destDir}"
    if ! read -q '?proceed (y/n)? '; then
        print;print "exiting ..."
        exit 1
    fi
    print
    
    #####
    nextFilename() {
        # copy from above
    }
    for src in "${sourceFilenames[@]}"; do
        # use the source file basename to determine the next name
        local dest=$(nextFilename $destDir/${src:t})
        print
        print "Executing: cp -v $src $dest"
        print "  Source directory: ${src:h}"
        print "  Source name:      ${src:t}"
        print "  Target directory: ${dest:h}"
        print "  Target name:      ${dest:t}"
        cp -v "$src" "$dest"
    done
    
    • 4

relate perguntas

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

  • Necessidade de algumas chamadas de sistema

  • astyle não altera a formatação do arquivo de origem

  • Passe o sistema de arquivos raiz por rótulo para o kernel do Linux

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve