移动一组文件,提示用户确认每个文件


9

系统:Ubuntu MATE 18.04

我有一个文件集合(在目录结构中的多个目录中),我想将其中的许多文件移到另一个目录中。我可以通过名称来区分要移动的文件(它们是配方标题),但是没有其他方法可以区分要移动的文件和不想移动的文件。我需要通过自己检查名称来决定每个文件。

因此,我要为每个要移动的文件运行一次命令,例如

mv Snacks/OkaraCrackers NeedsTesting/
mv Snacks/SunflowerBrittle NeedsTesting/
mv Treats/ChocolateChilliFudge NeedsTesting/
mv Treats/PecanBlondies NeedsTesting/

即使使用制表符补全,这也太多了。我真正想做的是

shopt -s globstar
mv --prompt-me-for-every-file ** NeedsTesting/

因此,我只需按yn每个文件即可。

如何移动一组文件并提示每个文件进行确认?

Answers:


6

方法1:在图形文件浏览器中,使用树状视图

我假设您的实际目标是为每个文件做出选择,而不是严格按照提示进行选择。但是,如果希望在终端中提示有关每个文件的信息,请参阅下面的方法2。

大多数图形文件浏览器都支持树状视图,您可以在其中一起查看目录层次结构的多个级别。您可以将文件复制或移动到该视图之外,可以单独或通过选择它们,然后对整个选择进行操作。即使来自多个文件夹的文件也可以使用。

在某些文件浏览器中,必须进入“首选项”菜单才能启用树视图。在MATE文件浏览器Caja中,始终在列表视图中启用它。单击查看→列表(或按Ctrl+ 2)切换到列表视图。每个目录在其左侧都有一个向右的小三角形,表示可以扩展。要展开文件夹,请单击该三角形,或在选择文件夹后按(向右箭头)键。在此示例中,我一个一个地选择了它们,并立即将它们全部拖到目的地:

在Caja文件浏览器中以树形结构选择的多个文件被拖到另一个文件夹中但尚未移动

假设源和目标位于同一驱动器上,则默认情况下拖动动作。如果您想复制,则按住该Ctrl键。

拖动完成后的情况,其中所选文件现在都放在目标文件夹中,而不是原来的单独位置中

从理论上讲,使用此方法时很容易纠正错误,因为大多数文件浏览器(包括Caja)都支持Ctrl+ Z撤消最近的操作,包括批处理操作。但是,我对此感到好运。有时文件会回到错误的文件夹中。

好消息是,您似乎正在处理大多数文本文档,而文本文档通常较小,因此您可以先进行一次额外的备份而tar不会遇到很多麻烦。无论您使用哪种方法,我都建议这样做。

方法2:将find与指令-ok动作

find查找文件并将它们的路径传递给带有-exec-execdir操作的任意外部命令是常见的用法。而且在每次运行命令之前find都有-okand -okdir该提示。如果您真的想在终端中提示有关每个文件的信息,我认为这是要走的路。

完成以产生如上所示的相同效果时,看起来像这样:

ek@Gnar:~$ find Texts -xtype f -ok mv -t 'Glorious Destination Folder' {} \;
< mv ... Texts/Robert Frost/New Hampshire.pdf > ? y
< mv ... Texts/Robert Frost/In The Clearing.pdf > ? n
< mv ... Texts/Helen Keller/The Story of My Life.pdf > ? y
< mv ... Texts/Saki/The Short Stories of Saki.pdf > ? y
< mv ... Texts/Jane Austen/Sense and Sensibility.pdf > ? n
< mv ... Texts/Jane Austen/Pride and Prejudice.pdf > ? y
< mv ... Texts/Richard Connell/The Stolen Crime.pdf > ? n
< mv ... Texts/Richard Connell/The Most Dangerous Game.txt > ? y
< mv ... Texts/Mary Wollstonecraft Shelley/Mathilda.epub > ? n
< mv ... Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf > ? y
< mv ... Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf > ? n
< mv ... Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm > ? y

替换Texts为源目录(.如果您已访问源目录,则为该目录cd),并Glorious Destination Folder替换为实际的目标目录。

每个文件运行一个命令。与-exec和不同-execdir-ok并且-okdir不支持+\;同一命令调用中传递多个找到的路径。因此,您不需要使用的-t dest形式mv。我建议这样做,无论如何,不过,无论是在一般使用find,特别是在这种情况下,这样的提示看起来更像是他们引发了人们的命令。

在编写该命令时,如果find遇到最终指向常规文件的符号链接,则会移动而不是忽略它(链接,而不是目标)。如果您确实只想操作一个常规文件,请使用-type f代替-xtype f

您可能需要在script会话中执行此操作,以便弄清楚如果出错了会发生什么。但是同样,没有理由不进行备份。

方法3:生成清单并对其进行编辑

至少只要文件名中没有换行符,您就可以使用一个简单的find命令来生成清单-一个列出您感兴趣的文件名(在这种情况下,可能是该文件名)的文件开始:

find Texts -xtype f >manifest

manifest您喜欢的名称替换列出正在考虑的文件的文件名(并相应调整其余方向)。

如上所述,Texts用实际的源目录替换,.如果您已经cd去过的话。但是,如果Texts是相对路径(包括.),则应确保稍后在实际执行移动时位于同一位置

运行该find命令后,manifest在文本编辑器中打开。这可能是nanovimemacsgeditpluma,等在编辑器中,进行评论是名称的文件,你行希望通过将移动#他们的开始。即使编辑器无法识别您知道具有注释的任何格式的文件,某些编辑器也会以不同的方式突出显示这些行。但是,大多数情况不会,我建议这样做的真正原因是,作为人类,您可能会在配置文件(甚至源代码)中注释掉行。我觉得这是更直观,且不易出错,那将是比来标记你的线条不想动了。

当然,您可以只删除不想移动的文件的行。注释掉它们的好处是,稍后您会清楚自己做了什么。

在我的示例中,这是编辑后文件内容的样子:

Texts/Robert Frost/New Hampshire.pdf
# Texts/Robert Frost/In The Clearing.pdf
Texts/Helen Keller/The Story of My Life.pdf
Texts/Saki/The Short Stories of Saki.pdf
# Texts/Jane Austen/Sense and Sensibility.pdf
Texts/Jane Austen/Pride and Prejudice.pdf
# Texts/Richard Connell/The Stolen Crime.pdf
Texts/Richard Connell/The Most Dangerous Game.txt
# Texts/Mary Wollstonecraft Shelley/Mathilda.epub
Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf
# Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf
Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm

然后,您可以使用过滤掉注释行,grep并将结果xargs通过管道传递给它们mv

grep -Pv '^\s*#' manifest | xargs -d '\n' mv -t 'Glorious Destination Folder'

如上所述,替换Glorious Destination Folder为实际目的地的名称。而已; 您的文件已移动。如果愿意,您当然可以在写echo之前mv先查看将首先运行的命令。

该命令的工作方式是:

  1. grep命令输出线从manifest-v)启动(^带有可选的() *)空白(\s)后跟一个文字#字符。该-P标志选择PCRE作为正则表达式的方言(这使\s我认为比传统更具可读性[[:space:]])。
  2. xargs命令将其输入(即的输出grep)划分为以换行符结尾的字段(-d '\n'),然后在mv -t 'Glorious Destination Folder'运行命令的末尾将每个字段(不包含换行符结尾)粘贴为单独的参数。

1
-ok恕我直言最好的答案
pim

7

这是一个小脚本(mv-confirm.sh):

#!/bin/bash

# Just make sure there are at least one source and one destination
if [ "$#" -lt 2 ]; then
    echo "Illegal number of parameters"
fi

DESTINATION=${*:$#}             # last argument
SOURCES=( ${@:1:$#-1} )         # all but last arguments

for i in "${SOURCES[@]}"
do
    read -p "move '$i' to '$DESTINATION' ? [y/n] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
        echo mv "$i" "$DESTINATION"
    fi
done

样品使用:

./mv-confirm.sh ** somewhere
move 'a' to 'somewhere' ? [y/n] n
move 'b' to 'somewhere' ? [y/n] y
mv b d
...

不要忘记使脚本可执行(chmod +x mv-confirm.sh)

NB

由于我不想弄乱您的文件,因此echo在实际mv 命令之前添加了。随意删除它以实际移动文件。

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.