如何用python复制文件和文件夹

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用python复制文件和文件夹相关的知识,希望对你有一定的参考价值。

参考技术A 这个方法不能把文件夹复制到文件夹里面去。

10.shutil.copytree('E:\test\good', 'E:\test\vivi')

copytree不能把文件夹复制到已存在的文件夹里面去。

11.shutil.copytree('E:\test\good', 'E:\test\new folder')

只能复制到新创建的文件夹里面。

有相同名字的文件,就会出错,注意修改文件名。

如何用反斜杠和空格“\”替换空格,以便 bash shell 脚本可以从 .tsv 文件中读取文件名并执行 rsync 复制

【中文标题】如何用反斜杠和空格“\\”替换空格,以便 bash shell 脚本可以从 .tsv 文件中读取文件名并执行 rsync 复制【英文标题】:How to replace a space with backslash and space "\ " so bash shell script can read the file name from a .tsv file and perform rsync copy如何用反斜杠和空格“\”替换空格,以便 bash shell 脚本可以从 .tsv 文件中读取文件名并执行 rsync 复制 【发布时间】:2021-12-16 13:52:27 【问题描述】:

我有一个脚本,它从一个用空格分隔的 tsv 文件中获取源和目标信息。第一列表示源文件路径,第二列是目标。我的 rsync 命令读取源和目标信息并执行复制操作。

但问题是源文件和目标文件都包含带空格的文件名(header-background copy.jpg),我们知道当 bash shell 读取文件名(带空格)时,它会用反斜杠替换空格,然后空格“\”

/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg /mapped-data/data20/data3/header-background copy.jpg

我的问题是如何用“\”替换空格,以便 shell 可以读取它。我尝试使用以下 sed 命令

sed -r 's/^\s+//;s/\s+/\\ /g' test2.tsv

但存在一个问题,因为上面的 sed 命令还在源路径后添加了一个反斜杠。正如我所提到的,我的脚本从 .tsv 文件中获取源和目标信息,因此添加斜杠是一个问题。下面是 sed 命令的输出。

/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background\ copy.jpg\ /mapped-data/data20/data3/header-background\ copy.jpg

我想要的是隐蔽的

/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg /mapped-data/data20/data3/header-background copy.jpg

/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background\ copy.jpg /mapped-data/data20/data3/header-background\ copy.jpg

【问题讨论】:

and as we know that when bash shell reads a file name (with space), it replace the space with backslash followed by space “\ ” 不,它不会那样工作。 like covert from确定你只想转换字符串吗?为什么不运行 rsync 呢?传递带有\ 的字符串仍然会在空格上分割,\ 是无关紧要的。试试看:a='abc\ def' ; printf "%s\n" $aa tsv file separated by space原来是TSV文件,所以字段用制表符分隔?如果是这样,请在选项卡上拆分字符串并使用两个变量。 @KamilCuk 可能需要对字符串进行显式转义,例如 scp file.txt user@server:'path\ with\ space/' TSV 文件的标准转义机制是使用引号。反斜杠在常规 TSV 文件中没有特殊意义。如果您想使用标准格式,可能要遵守其约定,而不是自行破解。 【参考方案1】:

使用sed,一种方法是对匹配进行分组并返回它,并在后面添加一个反斜杠

sed 's/\([A-Za-z0-9\/][^\.]*\) /\1\\ /g' input_file
/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background\ copy.jpg   /mapped-data/data20/data3/header-background\ copy.jpg

【讨论】:

非常感谢HatLess!这正是我正在寻找的(使用流编辑器的解决方案)。 @mht.haque 此解决方案有其局限性:每个路径只能有一个空格,并且文件名必须具有扩展名。不过,这可能足以满足您的需求 @Fravadona 我也意识到了这一点。此 sed 解决方法适用于我的 rsync 用例,但不适用于 aws s3。由于 aws s3 cp 命令需要将这些路径双引号。在 tsv 文件中双引号这些路径之前,它给了我 错误。【参考方案2】:

tsv 文件以空格分隔

至少使用tab,因为tab 出现在路径中的可能性低于space

备注:你知道只有/\0(NULL 字节)是Linux 文件系统中文件名的禁止字符吗?这意味着除了\0 之外的所有内容都可以出现在路径中...

假设您的文件现在以tab 分隔,并且您的路径不包括newlinestabs。在 BASH 中阅读它的方法如下:

while IFS=$'\t' read -r filepath1 filepath2
do
    declare -p filepath1 filepath2
done <<< "/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg"$'\t'"/mapped-data/data20/data3/header-background copy.jpg"

输出:

declare -- filepath1="/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg"
declare -- filepath2="/mapped-data/data20/data3/header-background copy.jpg"

如果您需要显式转义一个变量(例如在scprsync 的远程部分),那么您可以像这样使用printf '%q'

rsync -av "$filepath1" user@server:"$(printf '%q' "$filepath2")"

【讨论】:

【参考方案3】:

使用参数替换拆分列:

while IFS= read -r line; do
    # count raw tabs to validate format
    tabs=$line//[!$'\t']
    tabs=$#tabs

    if ((tabs!=1)); then
        echo "$line//$'\t'/TAB: less or more than one raw tab, skipping…" >&2
    else
        # split by tab
        source=$line%$'\t'*
        target=$line#*$'\t'

        rsync "$source" "$target"
    fi

done < list.tsv

循环检查每一行是否只有一个制表符,如果没有则跳过它。添加您的rsync 选项等。

确保列表没有符号转义字符(如 \t\n),或任何其他不属于文字文件名的转义/引号。 tsvcsv 可以有各种不同的非文字引用,需要正确解析。

还要注意rsync 的这种用法,用于将文件名从列表文件复制到单个目标:rsync [opts] —files-from="my-source-list" /my/target/

【讨论】:

以上是关于如何用python复制文件和文件夹的主要内容,如果未能解决你的问题,请参考以下文章

如何用反斜杠和空格“\”替换空格,以便 bash shell 脚本可以从 .tsv 文件中读取文件名并执行 rsync 复制

linux下如何用脚本复制其他电脑上的文件

如何用给定的信号终止python程序? [复制]

如何用bat复制一个文件夹到另一个文件夹去?

如何用COPY命令把当前选中的文件复制到指定文件夹内

如何用cmd快速异名复制文件