移动除一个文件以外的所有文件
1. 简介
在使用 Linux 时,有时我们可能需要移动多个文件并留下一个或多个文件。在本文中,我们将研究几种实现此类结果的方法。
2. 蛮力方法
让我们从蛮力或文字方法开始。简单地说,我们在mv 命令之后列出了我们想要重定位的所有文件,除了不需要的文件。本质上,我们以最基本的形式使用mv命令。**因此,我们实际上是在没有任何技术来隔离不需要的文件的情况下传输想要的文件。**这确实要求我们至少在文件的源目录中进行操作:
/source_dir$ ls
file1 file2 file3 file4 file5
/source_dir$ mv file1 file2 file3 file4 ~/target_dir/
/source_dir$ ls ~/target_dir/
file1 file2 file3 file4
这种方法可能看起来效率低下,但是,当您移动一个文件或比那些不需要的文件少的文件时,它会派上用场,并且正则表达式将无能或使事情复杂化。
3. 重命名不需要的文件
接下来,我们可以将不需要的文件重命名为隐藏文件,因为mv默认不检测隐藏文件。因此,在重命名不需要的文件后,我们将使用星号*正则表达式来移动其余文件:
/source_dir$ mv file5 .file5
/source_dir$ mv * ~/target_dir/
/source_dir$ ls -la
total 0
drwxrwxr-x 2 ubuntu ubuntu 60 Jun 10 03:42 .
drwxr-xr-x 21 ubuntu ubuntu 520 Jun 10 03:25 ..
-rw-rw-r-- 1 ubuntu ubuntu 0 Jun 10 00:57 .file5
移动文件后,我们可以将隐藏文件重命名为其原始名称:
/source_dir$ mv .file5 file5
4. 使用感叹号否定格式
第三种方法使用感叹号作为不需要的文件名之前的前缀,用括号括起来。这指示操作系统查找除表示的文件之外的所有其他文件:
$ mv SOURCE_DIRECTORY/!(unwanted_filename) TARGET_DIRECTORY
要使用这种格式,我们首先需要将*shopt -s extglob*命令添加到.bashrc 配置文件中。这告诉 Linux 允许在路径名扩展上进行模式匹配:
$ set shopt -s extglob .bashrc
$ mv source_dir/!(file5) target_dir/
5. 使用插入符号否定格式
第四种方法非常类似于感叹号否定格式。这种方法在不需要的文件之前放置一个插入符号^*,将其与要重定位的其他文件隔离开来*:
% mv SOURCE_DIRECTORY/^UNWANTED_FILENAME TARGET_DIRECTORY
但是,使用这种方法有一些限制。首先,此方法仅适用于 z shell zsh 。其次,我们需要设置扩展的全局 shell 选项EXTENDED_GLOB ,也就是说,我们将从命令行运行*setopt extended_glob*。与上面的shopt -s extglob 一样,这告诉 Linux 允许在路径名扩展上进行模式匹配。有了这些协议,我们将把插入符号作为前缀放在不需要的文件之前。然后mv命令将传输除不需要的所有其他文件:
$ zsh
% setopt extended_glob
% mv source_dir/^file5 target_dir
6. 使用封闭或管道反向搜索
这些下一个子主题讨论了在评估了反引号 、“、子外壳 、$()或通过xargs -i操作管道传输的不需要的文件的隔离之后传输目标文件。**反引号和子 shell 创建了评估命令语句的封闭 shell 环境。**同一命令行中的其他命令使用所附语句的结果进行操作。这是命令替换 。
当通过管道传输到xargs -i操作时,** xargs从标准输入收集内容,并使它们可用于同一语句中的特色命令。-i选项截断或替换输入分隔符。**因此,空白分隔符替换了在结果输入中分隔内容的换行符或空格。xargs -i操作具有mv {} 语句。花括号{} 扩展了通过管道传输到xargs -i语句中的结果列表。
6.1. 使用反向ls搜索
在这种方法中,我们只需使用带有*-I选项的ls 命令,以不需要的文件作为索引进行反向搜索。这将显示除不需要的文件之外的所有其他文件。反过来,该命令语句在封闭的反引号内进行评估。然后mv*命令将封闭操作的结果传输到目标目录。要使此方法起作用,我们需要位于文件的源目录中:
/source_dir$ mv `ls -I file5` ~/target_dir/
代替反引号,我们可以使用子 shell 括起来:
/source_dir$ mv $(ls -I file5) ~/target_dir/
我们还可以将 ls-I Wanted_filename的结果通过管道传输 到 xargs-i语句中,该语句将反向搜索的结果传输到目标目录:
/source_dir$ ls -I file5 | xargs -i mv {} ~/target_dir/
6.2. 使用反向grep搜索
此方法使用ls列出源目录内容并通过*grep -v*管道进行反向搜索。** grep -v搜索使用不需要的文件作为索引来列出所有其他文件。现在,反引号包含并评估整个管道操作。此后,mv命令将反引号括起来的操作中列出的文件传输到目标目录:**
/source_dir$ mv `ls | grep -v file5` ~/target_dir/
代替反引号,我们可以使用子 shell 括起来:
/source_dir$ mv $(ls | grep -v file5) ~/target_dir/
我们还可以将grep -v的结果通过管道转换为xargs-i语句,该语句将反向搜索的结果传输到目标目录:
/source_dir$ ls | grep -v file5 | xargs -i mv {} ~/target_dir
6.3. 将find与反向grep搜索一起使用
此技术使用find 命令列出源目录的内容。有一个-type f参数指示find*命令只搜索常规文件*。然后将**结果传送到反向grep搜索中,该搜索使用不需要的文件作为索引来列出所有其他文件。**反引号包围并评估整个操作。然后mv命令将封闭操作的结果传输到目标目录:
$ mv `find source_dir/ -type f | grep -v file5` target_dir/
代替反引号,我们可以使用子 shell 括起来:
$ mv $(find source_dir/ -type f | grep -v file5) target_dir/
我们还可以将反向查找*/grep搜索的结果通过管道传输到xargs-i*语句中,该语句将反向搜索的结果传输到目标目录:
$ find source_dir/ -type f | grep -v file5 | xargs -i mv {} target_dir/
**注意:**此方法在脚本中使用是安全的,因为它既不需要预先设置,也不需要遵守协议,也不需要位于源目录中。
6.4. 使用sed搜索和替换
此方法使用反引号括起一个搜索不需要的文件并将其显示替换为空条目的sed 语句。**该搜索然后通过管道返回到一个echo 命令,该命令列出了源目录的所有其他内容。**因此,列出的是除不需要的所有其他文件。此后,mv命令将列出的内容的结果传输到目标位置:
/source_dir$ mv `echo * | sed s:file5::g` ~/target_dir/
代替反引号,我们可以使用子 shell 括起来:
/source_dir$ mv $(echo * | sed s:file5::g) ~/target_dir/
**我们还可以 通过带有mv {}语句的xargs -i来管道sed搜索和替换操作 。**我们必须在xargs -i和mv {}之间包含花括号{} ,因为管道 echo/ sed语句会生成一个字符串。有必要扩展该字符串以便mv对其进行评估。指定给mv命令的花括号依次评估新扩展的内容。
/source_dir$ echo * | sed s:file5::g | xargs -i {} mv {} ~/target_dir/
6.5. 使用带有xargs的find命令
最后,find命令可以与xargs命令一起使用。此方法是另一种可以在脚本中安全使用的技术,因为没有事先设置或协议,也不需要在源目录中。** find命令用于通过xargs操作列出和移动源目录的内容。**
find命令有几个选项。第一个是*-maxdepth 1*,它禁止重复到其他文件夹。第二个是*-mindepth 1*,它防止源文件夹包含在要传输的结果中。第三个选项是*-not -name* 不需要的文件名选项,它使用不需要的文件名作为索引来列出剩余内容。第四个是选项类型* -f*,它只包括列出的结果中的文件。最后是*-print0*选项,它创建由空字符分隔的列表,删除任何空格和/或引号。
然后将该列表通过管道传送到一个xargs -0操作,该操作收集文件名列表并使用mv -t将它们传输到目标目录:
$ find source_dir/ -maxdepth 1 -mindepth 1 -not -name file5 -type f -print0 | xargs -0 mv -t target_dir/
我们已经知道xargs 从标准输入中收集内容。指定选项*-0是因为空字符分隔输入,因此使用-print0*选项。mv -t实质上指示将源内容传输到目标目录。
我们可以消除xargs -0 并使用反引号将find操作括起来而不使用*-print0*,因为结果不需要空字符来分隔,然后通过mv命令将结果传输到目标目录:
$ mv `find source_dir/ -maxdepth 1 -mindepth 1 -not -name file5 -type f` target_dir/
此外,我们可以使用子 shell 来包含查找操作,而不是反引号:
$ mv $(find source_dir/ -maxdepth 1 -mindepth 1 -not -name file5 -type f) target_dir/