Linux下进行文件的解压、复制、移动应该是最常见的操作了。尤其是我们在项目中使用大量的数据集文件(比如机器学习)时。然而使用这些命令时一不留神就会掉进坑里,这篇文章我们就来细数用Shell进行文件操作的这些坑。

将文件单个地进行压缩与解压

Linux下压缩文件的常见扩展名包括.gz.tar.tar.gz, .zip等。这些压缩格式都能够跨平台(Windows/Mac/Linux)使用。下面我们以.zip文件为例子来讲解。我们已知一个文本文件压缩包test.zip,想把它解压,很简单,运行unzip命令即可:

orion-orion@MacBook-Pro Learn-Linux % unzip test.zip
Archive: test.zip
inflating: test.txt

如果我们想要将test.txt重新压缩呢?你可能情不自禁会执行zip test.txt ,然后我们发现提示:

orion-orion@MacBook-Pro Learn-Linux % zip test.txt
zip warning: missing end signature--probably not a zip file (did you
zip warning: remember to use binary mode when you transferred it?)
zip warning: (if you are trying to read a damaged archive try -F) zip error: Zip file structure invalid (test.txt)

其实是传参数传错了,导致zip误把test.txt当成压缩后的文件名了,这当然不是合法的。我们看zip的参数构成:

zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]

[-b path] 是压缩后的.zip文件的路径,zipfile list是待压缩的文件列表。于是,我们这样写即可成功压缩:

orion-orion@MacBook-Pro Learn-Linux % zip test2.zip test.txt
adding: test.txt (stored 0%)

当然,zip也支持将多个文件压缩:

orion-orion@MacBook-Pro Learn-Linux % zip test3.zip test.txt test2.txt
adding: test.txt (stored 0%)
adding: test2.txt (stored 0%)

此时我们发现再解压test3.zip会发现重新得到了两个原始文件:

orion-orion@MacBook-Pro Learn-Linux % unzip test3.zip
Archive: test3.zip
extracting: test.txt
extracting: test2.txt

zip也支持对目录压缩,如我们尝试压缩test目录:

orion-orion@MacBook-Pro Learn-Linux % zip test4.zip test
adding: test/ (stored 0%)

此时再解压test4.zip则会重新生成test目录:

orion-orion@MacBook-Pro Learn-Linux % unzip test4.zip
Archive: test4.zip
creating: test/

不过,zip是将输入的文件列表分别进行压缩的操作,即是对目录来进行压缩也是对目录内的所有文件one-by-one的操作。那我们需要将很多文件先打包成一个文件,然后再压缩呢?此时就要用到tar了。

tar:打包命令

很多人误解tar是个压缩命令,其实压缩命令是gzipxz以及我们上文提到的zip这些。tar是个打包命令,只不过附带压缩与解压的功能。tar的选项多如牛毛,为了减轻大家的记忆负担,我们只介绍下面两个选项:

-c: 建立打包文件(可搭配-v将过程中打包的文件可视化);

-x:解包或解压缩的功能(可搭配-C在特定目录解压);

(其实还有表示通过gzip进行压缩/解压缩的-z,通过bzip2的支持进行压缩/解压缩的-j,通过xz的支持进行压缩解压缩的-J等,但我们这里统一用.zip示范,就省去这些参数了)

那么,我们只需要记住下面的命令即可:

压缩: tar -cv -f filename.zip 要被压缩的文件或目录名称

解压缩:tar -xv -f filename.zip -C 欲解压的目录(这个目录必须已经存在)

注意,压缩传参顺序是压缩后的.zip文件在前,压缩前的文件在后,别搞错了。(让人联想到gcc编译器,不过gcc传参时规定是-o output_file.out的形式来指定输出的可执行文件,就回避了这个顺序问题)

比如,我们要将test文件夹(该文件夹下有一个test.txt文件)压缩,可以运行如下命令:

orion-orion@MacBook-Pro Learn-Linux % tar -cv -f test4.zip test
a test
a test/test.txt

然后将其解压到当前目录,可运行如下命令:

orion-orion@MacBook-Pro Learn-Linux % tar -xv -f test4.zip -C .
x test/
x test/test.txt

对多个文件压缩:

orion-orion@MacBook-Pro Learn-Linux % tar -cv -f test3.zip test.txt test2.txt
a test.txt
a test2.txt

然后将其解压到当前目录:

orion-orion@MacBook-Pro Learn-Linux % tar -xv -f test3.zip -C .
x test.txt
x test2.txt

由上面所说,zip/unziptar都是压缩什么解压出来就是什么,原来是目录就是目录,原来没目录不会帮你自动生成一个目录,但Linux或Mac系统的可视化压缩工具就不一样了(在Mac中被称为「归档实用工具」)。Mac中对目录压缩时压缩命令和tar命令是等效的,比如我们想用Mac自带的压缩工具压缩test文件夹:

会生成对应的归档文件:

再解压会得到同样的文件夹(会自动帮我们重命名),不会帮我们生成多余的目录:

然而,如果我们尝试用Mac自带的压缩工具压缩多个文件:

它会自动帮我们生成一个名为归档.zip的文件:

然后,如果此时我们尝试对归档.zip文件进行解压,会发现系统会自动帮我们生成一个名为归档 的文件夹:

这个文件夹内部才是我们需要的文件:

这在对大量文件操作时需要额外注意,否则会白白开销你一次拷贝文件的时间!

文件拷贝

我们紧接上面的情景。假设我们当前的目录为项目目录,而我们手滑使用了系统自带的可视化解压工具生成了一个多余的目录。我们接下来要把系统生成的多余的归档文件夹里的文件拷贝到当前目录,那么我们可以使用带r参数的cp命令:

orion-orion@MacBook-Pro Learn-Linux % cp -r 归档/ .
orion-orion@MacBook-Pro Learn-Linux % ls
test.txt test2.txt 归档

这里-r参数表示递归复制命令,用于目录的递归复制。注意命令中的归档/表示归档目录下的所有文件,意思和归档/*相同:

orion-orion@MacBook-Pro Learn-Linux % cp -r 归档/* .
orion-orion@MacBook-Pro Learn-Linux % ls
test.txt test2.txt 归档

选项参数-r写成-R是等效的:

orion-orion@MacBook-Pro Learn-Linux % cp -R 归档/* .
orion-orion@MacBook-Pro Learn-Linux % ls
test.txt test2.txt 归档

但如果直接传入参数归档,则表示将这个目录整个地复制:

orion-orion@MacBook-Pro Learn-Linux % cp -r 归档 .
cp: ./归档 and 归档 are identical (not copied).

同一个目录下不可能有两个相同名称的子目录,这当然就会出错,当然我们可以将其复制到另外一个目录里:

orion-orion@MacBook-Pro Learn-Linux % cp -r 归档 /tmp
orion-orion@MacBook-Pro Learn-Linux % ls /tmp |grep 归档
归档

你可能要问,加r和不加r有啥区别?如果不加r,则默认是跳过目录的,也就是说只能copy文件:

orion-orion@MacBook-Pro Learn-Linux % cp  归档/ .
cp: 归档/ is a directory (not copied).
orion-orion@MacBook-Pro Learn-Linux % cp 归档 /tmp
cp: 归档 is a directory (not copied).

文件移动

我们还是紧接着上面的场景。假定我们已经将归档文件夹中的test.txttest2.txt成功拷贝到当前项目目录了。现在我们有了个新的需求:我们在项目目录中建了一个data子目录,现在需要将项目目录中的test.txttest2.txt移动到data子目录中。这就需要如下命令:

orion-orion@MacBook-Pro Learn-Linux % mv test2.txt test.txt data
orion-orion@MacBook-Pro Learn-Linux % ls data
test.txt test2.txt

注意,如果有多个源文件或目录,则最后一个目标文件(也就是这里的data)一定是目录。当我们只移动一个文件时,就有潜在的二义性。这里因为data目录本身存在,我们移动test.txtdata目录还能正常执行:

orion-orion@MacBook-Pro Learn-Linux % mv test.txt data
orion-orion@MacBook-Pro Learn-Linux % ls data
test.txt

但是如果data目录不存在,就会将mv解释为重命名的意思,比如如果我们将data目录删除再执行:

orion-orion@MacBook-Pro Learn-Linux % mv test.txt data

此时就等效于把test.txt更名为data文件:

orion-orion@MacBook-Pro Learn-Linux % ls -l|grep data
-rw-r--r-- 1 orion-orion staff 0 4 20 22:01 data

可以看出,第一个字母是-,也就意味着data是普通文件,不是目录(是目录的话第一个字母是d)。

因此,使用mv语句时要格外小心,因为它既有移动到目录的作用,也有重命名的作用,一不注意就可能出错!

引用

Linux:文件解压、复制和移动的若干坑的更多相关文章

  1. linux 文件解压

    解压 tar -xvf file.tar //解压 tar包 tar -xzvf file.tar.gz //解压tar.gz tar -xjvf file.tar.bz2   //解压 tar.bz ...

  2. linux压缩解压文件

    首先进入文件夹 cd /home/ftp2/1520/web 压缩方法一:压缩web下的888.com网站 zip -r 888.com.zip888.com 压缩方法二:将当前目录下的所有文件和文件 ...

  3. Linux:文件解压与压缩

    文件打包与压缩 常见压缩文件格式: |文件后缀名 |说明| |.zip |zip程序打包压缩的文件| |.rar |rar程序压缩的文件| |.7z |7zip程序压缩的文件| |.tar |tar程 ...

  4. 【Linux命令】linux一次性解压多个.gz或者.tar.gz文件

    原文:linux一次性解压多个.gz或者.tar.gz文件 解压多个压缩包 对于解压多个.gz文件的,用此命令: for gz in *.gz; do gunzip $gz; done 对于解压多个. ...

  5. Linux 下面解压.tar.gz 和.gz文件解压的方式

    Linux 下面解压.tar.gz 和.gz文件解压的方式 两种解压方式 1 .tar.gz 使用tar命令进行解压 tar -zxvf java.tar.gz 解压到指定的文件夹 tar -zxvf ...

  6. linux中解压rar文件

    linux平台默认是不支持RAR文件的解压,需要安装linux版本的RAR压缩软件,下载地址为:http://www.rarlab.com/download.htm 下载之后进行解压之后,进入rar目 ...

  7. [Linux]-Linux常用命令之文件解压

    不压缩方式压缩的文件需要不同的命令来解压缩,下面是Linux的各种文件解压命令. 对于.tar结尾的文件: tar -xf 对于.gz结尾的文件 : gzip -d all.gz gunzip all ...

  8. linux压缩文件——解压方法

    linux下 tar解压 gz解压 bz2等各种解压文件使用方法 .tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar ...

  9. linux下压缩成zip文件解压zip文件

    linux  zip命令的基本用法是: zip [参数] [打包后的文件名] [打包的目录路径] linux  zip命令参数列表: -a     将文件转成ASCII模式 -F     尝试修复损坏 ...

  10. Linux压缩解压 tar.gz格式的文件.查看tomcat是否运行

    tar命令详解 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用 ...

随机推荐

  1. windows server 2008r2 在vmware里自动关机

    虚拟机没有激活所以导致自动关机,试试激活它.<wiz_tmp_tag id="wiz-table-range-border" contenteditable="fa ...

  2. Scanner几个问题与正则简介

    Pre:最近做了头条的在线笔试,对Scanner输入的处理有些特殊,当时是一脸懵逼态,遂由此随笔(/@_@\),java小白,有错难免! 查了下Scanner的源码,没有头绪,但是其中用到了正则的知识 ...

  3. Integer与int的区别?

    int是java提供的8种原始数据类型之一.Java为每个原始类型提供了封装类,Integer是java为int提供的封装类.int的默认值为0,而Integer的默认值为null,即Integer可 ...

  4. js Object扩展自定义方法,jQuery抛出 Uncaught TypeError: matchExpr[type].exec is not a function

    使用Jquery的时候,想在Object原型上添加自己扩展的方法的时候,启动项目之后,打开网页就会报如上错误信息,经过测试,可以在Object下的具体类型上进行扩展自定义方法,如String,Arra ...

  5. zookeeper 负载均衡和 nginx 负载均衡区别?

    zk 的负载均衡是可以调控,nginx 只是能调权重,其他需要可控的都需要自己写插件:但是 nginx 的吞吐量比 zk 大很多,应该说按业务选择用哪种方式.

  6. 集合流之“将List<Integer>转为String并用逗号分割”

    1.使用[流+Collectors]转换 import java.util.ArrayList; import java.util.List; import java.util.stream.Coll ...

  7. 制作任意波形发生器MAX038

  8. 顺利通过EMC实验(16)

  9. python实战----Todo清单续写

    添加分页功能 第一步:是对视图函数的改写,通过查询数据库数据,进行分页显示 # 修改清单显示的视图函数 @app.route('/list/') @app.route('/list/<int:p ...

  10. css布局基础总结

    前端css布局知识繁杂,实现方式多种多样.想写出高效.合理的布局,必须以深厚的css基础为前提.为了方便记忆和复习,将css布局要点记录如下.内容较多,应用方面说的不太详细,但都是很实用的点. 所谓布 ...