Simular a ação do comando mv

13

Estou movendo alguns arquivos e quero ter certeza de que o mvcomando digitado está correto antes de prosseguir e executá-lo.

Se eu estivesse usando apt-get, poderia usar o -ssinalizador para executar uma simulação que realmente faria qualquer coisa.

Tem mvuma função semelhante, que simularia a movimentação dos arquivos, mas na verdade não faria nada?

starbeamrainbowlabs
fonte
2
Em man mvque eu posso ver apenas o -i-flag, que pergunta antes de sobrescrever
Kev Inski
2
mvcomando não tem simulatenada, mas posso escrever uma função que faz uma verificação como essa. Como está essa solução?
Sergiy Kolodyazhnyy
2
E como você espera que a simulação seja? Simplesmente imprima uma linha por arquivo modificado, digitando, por exemplo, "Renomeado a.txt para b, txt" ou "Movido /home/you/a.txt para /home/you/Documents/a.txt"?
Byte Commander
@ByteCommander Algo assim, sim. Estou paranóico ao cometer um erro ao mover meus certificados SSL privados para organizá-los.
starbeamrainbowlabs
4
A -nopção para mvgarantir que você não possa sobrescrever nenhum arquivo por engano, não é uma resposta, mas é sempre útil saber.
Arronical

Respostas:

2

Este script deve fazer o truque. Ele também pode lidar com vários arquivos / diretórios de origem. Use da mesma maneira que você usaria mv- mvsim source... dest. Observe que ele não presta atenção às opções, nem as filtra (apenas as trata como nomes de arquivos) e pode não funcionar bem com links simbólicos.

#!/bin/bash

if [ $# -lt 2 ]; then
    echo "Too few arguments given; at least 2 arguments are needed."
    exit 1
fi

lastArg="${@:$#}"

i=1
for param in "$@"; do
    if [ ! -e "$param" -a $i -lt $# ]; then
        echo "Error: $param does not exist."
        exit 1
    elif [ "$param" = "$lastArg" -a $i -lt $# ]; then
        echo "Error: $param is the same file/directory as the destination."
        exit 1
    fi
    ((i++))
done

if [ $# -eq 2 ]; then # special case for 2 arguments to make output look better
    if [ -d "$1" ]; then
        if [ -d "$2" ]; then
            echo "Moves directory $1 (and anything inside it) into directory $2"
            exit 0
        elif [ ! -e "$2" ]; then
            echo "Renames directory $1 to $2"
            exit 0
        else
            echo "Error: $2 is not a directory; mv cannot overwrite a non-directory with a directory."
            exit 1
        fi
    else
        if [ -d "$2" ]; then
            echo "Moves file $1 into directory $2"
        elif [ -e "$2" ]; then
            echo "Renames file $1 to $2, replacing file $2"
        else
            echo "Renames file $1 to $2"
        fi
        exit 0
    fi
elif [ ! -e "$lastArg" ]; then
    echo "Error: $lastArg does not exist."
    exit 1
elif [ ! -d "$lastArg" ]; then
    echo "Error: $lastArg is not a directory; mv cannot merge multiple files into one."
    exit 1
fi

argsLeft=$#
echo "Moves..."
for param in  "$@"; do
    if [ $argsLeft -eq 1 ]; then
        echo "...Into the directory $param" # has to be a directory because -f $lastArg was dealt with earlier
        exit 0
    fi
    if [ -d "$param" ]; then
        if [ ! -d "$lastArg" ]; then
            echo "Error: $lastArg is not a directory; mv cannot overwrite a non-directory with a directory."
            exit 1
        fi
        if [ $argsLeft -eq $# ]; then
            echo "The directory ${param} (and anything inside it)..."
        else
            echo "And the directory ${param} (and anything inside it)..."
        fi
    else
        if [ $argsLeft -eq $# ]; then
            echo "The file ${param}..."
        else
            echo "And the file ${param}..."
        fi
    fi
    ((argsLeft--))
done

Alguns exemplos:

$ ls
dir1  dir2  file1  file2  file3  mvsim
$ ./mvsim file1 file2
Renames file file1 to file2, replacing file file2
$ ./mvsim file1 newfile
Renames file file1 to newfile
$ ./mvsim file1 dir1
Moves file file1 into the directory dir1
$ ./mvsim file1 file2 file3 dir1
Moves...
The file file1...
And the file file2...
And the file file3...
...Into the directory dir1
$ ./mvsim file1 file2 dir1 dir2
Moves...
The file file1...
And the file file2...
And the directory dir1 (and anything inside it)...
...Into the directory dir2
$ ./mvsim file1 file2 file3 # error - file3 isn't a directory
Error: file3 is not a directory; mv cannot merge multiple files into one.
$ ./mvsim -f -i file1 dir1 # options aren't parsed or filtered out
Error: -f does not exist.
insert_name_here
fonte
Obrigado! Estou aceitando isso como a resposta sobre o script que Serg escreveu porque abrange mais de 2 argumentos. maybeparece bom também, mas acho que essa é a opção mais segura no momento.
Starbeamrainbowlabs
10

A função abaixo é para verificar verbalmente a mvsintaxe. Observe que ele funciona apenas com 2 argumentos, SOURCE e DESTINATION, e não verifica se há -tsinalizador.

A função deve ser colocada em ~/.bashrc. Para usá-lo imediatamente, abra um novo terminal ou executesource ~/.bashrc

mv_check()
{
    # Function for checking syntax of mv command 
    # sort of verbose dry run
    # NOTE !!! this doesn't support the -t flag
    # maybe it will in future (?)

    # check number of arguments  
    if [ $# -ne 2   ]; then
        echo "<<< ERROR: must have 2 arguments , but $# given "
        return 1
    fi

    # check if source item exist
    if ! readlink -e "$1" > /dev/null 
    then
        echo "<<< ERROR: " "$item" " doesn't exist"
        return 1
    fi

    # check where file goes

    if [ -d "$2"  ]
    then
        echo "Moving " "$1" " into " "$2" " directory"
    else
        echo "Renaming "  "$1" " to " "$2" 
    fi

}

Aqui estão alguns testes:

$> mv_check  TEST_FILE1  bin/python                                                                                      
Moving  TEST_FILE1  into  bin/python  directory
$> mv_check  TEST_FILE1  TEST_FILE2                                                                                      
Renaming  TEST_FILE1  to  TEST_FILE2
$> mv_check  TEST_FILE1  TEST_FILE 2                                                                                     
<<< ERROR: must have 2 arguments , but 3 given 
$> mv_check  TEST_FILE1  TEST_FILE\ 2                                                                                    
Renaming  TEST_FILE1  to  TEST_FILE 2
$> mv_check  TEST_FILE1  "TEST_FILE 2"                                                                                   
Renaming  TEST_FILE1  to  TEST_FILE 2
$> mv_check  TEST_FILE1                                                                                                  
<<< ERROR: must have 2 arguments , but 1 given 
Sergiy Kolodyazhnyy
fonte
1
Você deve adicionar ay / n para prosseguir e chamar o mv real. ;)
chaskes
6

Existe um programa no github chamado talvez, que pode ser o que você está procurando.

De acordo com a descrição do projeto, maybe

... permite que você execute um comando e veja o que ele faz com seus arquivos sem fazê-lo! Depois de revisar as operações listadas, você pode decidir se realmente deseja que essas coisas aconteçam ou não.

Por isso, também mostrará o que outros programas farão com seus arquivos, não apenas mv.

maybeprecisa do Python para executar, mas isso não deve ser um problema. É fácil instalá-lo ou compilá-lo usando o gerenciador de pacotes do Python.

O processo de instalação e o uso do programa são descritos na página inicial do projeto. Infelizmente, não tenho acesso a um sistema Linux no momento, portanto não posso fornecer exemplos de uso do programa.

maddin45
fonte
Como tudo soa bem, conforme a documentação: "nunca use maybepara executar código não confiável"!
grooveplex
@grooveplex Você não confia na implementação do mvseu sistema?
maddin45
sim, eu faço, mas ele foi concebido como um heads-up
grooveplex