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

Zan*_*nna 9 command-line files

系统:Ubuntu MATE 18.04。

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

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

mv Snacks/OkaraCrackers NeedsTesting/
mv Snacks/SunflowerBrittle NeedsTesting/
mv Treats/ChocolateChilliFudge NeedsTesting/
mv Treats/PecanBlondies NeedsTesting/
Run Code Online (Sandbox Code Playgroud)

即使使用选项卡完成,这也是打字太多。我真正想做的是

shopt -s globstar
mv --prompt-me-for-every-file ** NeedsTesting/
Run Code Online (Sandbox Code Playgroud)

所以我可以为每个文件按yn

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

pim*_*pim 8

这是一个小脚本 ( 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
Run Code Online (Sandbox Code Playgroud)

样品用途:

./mv-confirm.sh ** somewhere
move 'a' to 'somewhere' ? [y/n] n
move 'b' to 'somewhere' ? [y/n] y
mv b d
...
Run Code Online (Sandbox Code Playgroud)

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

NB

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


Eli*_*gan 6

方式 1:在您的图形文件浏览器中,使用树视图

我假设您的实际目标是为每个文件做出选择,而不是严格来说被提示。但是,如果您希望在终端中收到有关每个文件的提示,请参阅下面的方式 2。

大多数图形文件浏览器都支持树视图,您可以在其中一起查看目录层次结构的多个级别。您可以单独或通过选择文件然后对整个选择进行操作来将文件复制或移出此视图。这甚至适用于来自多个文件夹的文件。

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

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

假设源和目标在同一个驱动器上,默认情况下拖动会移动。如果您想复制,请按住该Ctrl键。

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

理论上,使用这种方法很容易修复错误,因为大多数文件浏览器(包括 Caja)都支持Ctrl+Z撤消最近的操作,包括批处理操作。然而,我的运气好坏参半。有时文件会回到错误的文件夹中。

好消息是,您似乎主要处理文本文档,这些文档往往很小,因此您可以轻松地进行额外备份tar。无论您使用什么方法,我都建议您这样做。

方式二find命令与-ok动作

通常用于find查找文件并将它们的路径传递给使用-exec-execdir操作的任意外部命令。而且每次运行命令之前find都有-ok-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
Run Code Online (Sandbox Code Playgroud)

替换Texts为源目录(.如果您愿意,可以是cd)和Glorious Destination Folder实际的目标目录。

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

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

您可能希望在script会话中执行此操作,以便在犯错时弄清楚发生了什么。但同样,没有理由不备份。

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

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

find Texts -xtype f >manifest
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

grep -Pv '^\s*#' manifest | xargs -d '\n' mv -t 'Glorious Destination Folder'
Run Code Online (Sandbox Code Playgroud)

如上,替换Glorious Destination Folder为实际目的地的名称。就是这样; 您的文件已移动。如果您愿意,您当然可以echo先编写mv以查看将首先运行的命令。

该命令的工作方式是:

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