模拟mv命令的动作


13

我正在移动一些文件,并且我想确保mv在继续运行之前输入的命令是正确的。

如果使用apt-get,则可以使用该-s标志执行实际上可以执行任何操作的模拟。

是否mv具有类似的功能,可以模拟文件的移动,但实际上不执行任何操作?


2
man mv我只能看到-i-flag,覆盖前,询问
千电子伏Inski

2
mv命令没有simulate东西,但是我可以编写一个执行类似检查的功能。那怎么解决?
Sergiy Kolodyazhnyy

2
您希望模拟看起来如何?只需为每个修改后的文件打印一行,例如“将a.txt重命名为b,txt”或“将/home/you/a.txt移至/home/you/Documents/a.txt”?
字节指挥官

@ByteCommander这样的,是的。我只是对在移动我的私人ssl证书进行组织时出错而感到偏执。
starbeamrainbowlabs

4
-n选项mv将确保您不会错误地覆盖任何文件,不是答案,但总是有用的。
Arronical

Answers:


2

这个脚本应该可以解决问题。它也可以处理多个源文件/目录。以与mv- 相同的方式使用它mvsim source... dest。请注意,它不注意选项,也不过滤掉它们(仅将它们视为文件名),并且可能不适用于符号链接。

#!/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

一些例子:

$ 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.

谢谢!我接受这个作为Serg编写的脚本的答案,因为它涵盖了2个以上的参数。maybe看起来也不错,但是我觉得这是目前比较安全的选择。
starbeamrainbowlabs '16

10

以下功能用于详细检查mv语法。请注意,它仅适用于2个参数SOURCE和DESTINATION,并且不检查-t标志。

该函数将放置在中~/.bashrc。要立即使用它,请打开新终端或运行source ~/.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

}

这是一些测试运行:

$> 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 

1
您应该添加ay / n才能调用实际的mv。;)
chaskes

6

github上有一个程序,也许叫做“ mayk” 。

根据他们的项目描述, maybe

...允许您运行命令并查看其对文件的作用,而无需实际执行!在查看了列出的操作之后,您可以决定是否确实希望发生这些事情。

因此,它不仅向您显示其他程序还将对您的文件执行什么操作mv

maybe需要Python才能运行,但这应该不是问题。使用Python的软件包管理器pip可以轻松安装或构建它。

程序的安装过程和用法均在项目的主页上进行了描述。不幸的是,目前我无法访问Linux系统,因此无法为您提供有关程序使用情况的任何示例。


根据文档,这听起来有多好:“切勿使用maybe运行不受信任的代码”!
凹槽复线

@grooveplex您不信任mv系统上的实现吗?
maddin45

是的,我愿意,但那是单挑的目的
grooveplex
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.