Linux 删除文件

本文将会讲述如何在Linux系统下删除文件的方法,以及如何在命令行下删除某个文件中特定的内容行, 或者删除特定日期创建的文件或者目录。

目录如下:

Linux 删除文件命令

在CentOS,Redhat,或者Ubuntu等类Unix系统下,我们主要用来删除文件或文件夹目录的方法是通过执行rm 命令或者 unlink命令。 下面我们来看删除文件命令rm的用法介绍:

rm 命令是Unix或者Linux系统下的主要用来文件系统中删除文件的命令。 当然,在大多数的系统里, 当我们想删除一个文件的时候,需要当前用对对该文件或者目录有写或者可执行的权限。

rm 命令格式:

rm {文件名}
rm [参数] {文件名}
unlink {文件名}
rm –f –r  {文件名}

 

rm 命令参数:

-f, –force 强制删除文件, 不做任何删除操作的提示

-I, –interactive  进行交互式的删除操作

-r, -R, –recursive 将对指定目录中的所有目录或子目录进行递归性的删除

-v, –verbose 显示删除操作的详细信息

–help 显示命令的使用帮助信息

通常情况下,我们会将-r 和-f来同时使用,这样就可以删除所有指定的文件或者目录,并且没有任何的操作提示信息输出。

Linux 删除单个文件夹或目录

让我们来看一个使用rm命令删除指定文件或者目录的例子, 假如你想删除当前目录下的一个文件名为fio.txt 的文件, 执行下面的命令:

# rm fio.txt

Linux 删除多个文件

如果想通过rm命令同时删除多个文件,可以将多个文件的文件名作为rm命令的参数, 执行下面的命令来删除当前目录下的fio1.txt, fio2.txt, fio3.txt 文件:

# rm fio1.txt  fio2.txt fio3.txt

命令输出如下:

root@devops:~/osetc# ls
fio1.txt  fio2.txt  fio3.txt

root@devops:~/osetc# rm fio1.txt fio2.txt fio3.txt

root@devops:~/osetc# ls
root@devops:~/osetc#

Linux 递归删除特定目录下的所有文件

如果要删除的目录里还包含了多层的子目录或者子目录依旧还有目录,那么如果想删除目录里的所有子目录和文件,这个时候我们需要使用rm命令的-rf参数,比如,如果你想删除当前目录下的fio目录,执行下面的命令:

# rm –rf fio

命令输出如下:

root@devops:~/osetc# ls fio
fio1.txt  fio2.txt  fio3.txt  subfio

root@devops:~/osetc# rm -rf fio

root@devops:~/osetc# ls fio
ls: 无法访问'fio': 没有那个文件或目录

root@devops:~/osetc#

Linux 删除文件并做删除前交互确认

如果你想在删除每个文件的时候,让系统都做出确认删除提示,那么这样可以让你不会错误的删除文件,比如要删除当前目录下的fio1.txt, 执行下面的命令:

# rm –I fio1.txt

命令输出如下:

root@devops:~/osetc# ls
fio1.txt

root@devops:~/osetc# rm -i fio1.txt
rm:是否删除普通文件 'fio1.txt'? y

root@devops:~/osetc# ls
root@devops:~/osetc#

Linux 显示删除文件时的信息

如果你想看到linux系统在删除你指定的文件或目录的时候,显示详细的处理信息,那么可以使用rm命令的-v选项,执行命令如下:

$ rm –v fio1.txt

命令输出如下:

root@devops:~/osetc# ls
fio1.txt

root@devops:~/osetc# rm -v fio1.txt
已删除'fio1.txt'

root@devops:~/osetc# ls
root@devops:~/osetc#

Linux系统下删除空目录文件

如果想删除特定目录下的,那么可以使用linux下的另一个命令rmdir, 执行下面命令:

# rmdir fio
# rmdir fio1

Linux下删除文件里的文件列表中的文件

如果某个文件里包含了很多需要删除的特定的文件路径, 那么我们可以使用rm命令并结合下xargs 命令来进行文件删除操作。

例如要删除当前目录下的fio.txt 文件中的列出的所有文件, 那么可以执行下面的命令:

# xargs rm -v < fio.txt

命令输出如下:

root@devops:~/osetc# cat fio.txt
/root/osetc/fio1/file1.txt
/root/osetc/fio1/file2.txt
/root/osetc/fio1/file3.txt

root@devops:~/osetc# xargs rm -v <fio.txt
已删除'/root/osetc/fio1/file1.txt'
已删除'/root/osetc/fio1/file2.txt'
已删除'/root/osetc/fio1/file3.txt'

注意:当你使用rm命令来删除文件的时候,千万不要运行”rm –rf / “ 命令, 因为这个命令会将linux系统的根目录下的所有文件都删除掉,这样的话,就会导致你的系统挂掉。

Linux删除文件名中以连字符或者减号开头的文件名

如果你想删除某个文件名中包含特殊字符的文件,无法直接使用rm 命令进行文件删除。 这个时候我们需要在rm命令后的加上双连字符,再跟文件名即可。 比如要删除-fio.txt文件,就可以执行下面的命令:

# rm -- -fio.txt

 Linux 通过文件的inode号删除文件

当我们在系统里看到文件名里包含乱码或者特殊字符的文件时候,如果简单的通过rm命令来删除文件的话,会失败的。 这个时候该怎么办? 我们可以通过文件唯一的inode号来进行删除操作。

我们需要结合find命令来根据文件的inode号来进行删除文件操作。

查看文件的inode

在linux系统里可以通过命令ll –i 来查看当前目录下的文件的详细信息,输出信息的第一列就是文件的inode号。 执行下面的命令:

#ll –I

命令输出如下:

root@devops:~/osetc# ll -i
总用量 16
131103 drwxr-xr-x 3 root root 4096 3月  14 22:56 ./
131073 drwx------ 6 root root 4096 3月  14 22:56 ../
262172 drwxr-xr-x 2 root root 4096 3月  14 22:57 fio1/
131106 -rw-r--r-- 1 root root   82 3月  14 22:56 fio.txt
131104 -rw-r--r-- 1 root root    5 3月  15 21:23 fio2.txt
131105 -rw-r--r-- 1 root root    5 3月  15 21:23 fio3.txt
131106 -rw-r--r-- 1 root root    5 3月  15 21:23 fio4.txt
131108 -rw-r--r-- 1 root root    5 3月  15 21:24 fio5.txt

通过find命令的delete参数进行文件删除

从上面的输出中,我们可以看到fio.txt 文件的inode号为131106, 通过执行下面的find命令并结合其-inum 参数来删除文件,执行下面的命令:

#find ./* -inum 131106 –delete

命令输出如下:

root@devops:~/osetc# find ./ -inum 131106 -delete
root@devops:~/osetc# ll -i
总用量 12
131103 drwxr-xr-x 3 root root 4096 3月  15 21:17 ./
131073 drwx------ 6 root root 4096 3月  14 22:56 ../
262172 drwxr-xr-x 2 root root 4096 3月  14 22:57 fio1/
131104 -rw-r--r-- 1 root root    5 3月  15 21:23 fio2.txt
131105 -rw-r--r-- 1 root root    5 3月  15 21:23 fio3.txt
131106 -rw-r--r-- 1 root root    5 3月  15 21:23 fio4.txt
131108 -rw-r--r-- 1 root root    5 3月  15 21:24 fio5.txt

通过find命令的exec参数并结合rm命令进行文件删除操作

我们也可以通过find命令的exec参数并结合rm删除命令来根据文件的inode号做文件的删除,执行下面的命令:

#find ./ -inum 131104 –exec rm –i {} \;

命令输出如下:

root@devops:~/osetc# find ./ -inum 131104
./fio2.txt

root@devops:~/osetc# find ./ -inum 131104 -exec rm -i {} \;
rm:是否删除普通文件 './fio2.txt'? y

root@devops:~/osetc# ll -i
总用量 24
131103 drwxr-xr-x 3 root root 4096 3月  15 21:29 ./
131073 drwx------ 6 root root 4096 3月  14 22:56 ../
262172 drwxr-xr-x 2 root root 4096 3月  14 22:57 fio1/
131105 -rw-r--r-- 1 root root    5 3月  15 21:23 fio3.txt
131106 -rw-r--r-- 1 root root    5 3月  15 21:23 fio4.txt
131108 -rw-r--r-- 1 root root    5 3月  15 21:24 fio5.txt

通过find命令并结合xargs来删除文件

当我们使用find命令查看到指定inode号的文件后,还可以结合xargs命令来进行文件的删除,执行命令如下:

# find ./ -inum 131105 |xargs rm -v

命令输出如下:

root@devops:~/osetc# find ./ -inum 131105
./fio3.txt

root@devops:~/osetc# find ./ -inum 131105 |xargs rm -v
已删除'./fio3.txt'

Linux 删除指定日期之前的文件

如果你想删除指定日期之前的所有的文件,这个时候我们需要通过linux下find命令并结合其-mtime参数进行文件的查找,在通过rm命令对查找到的文件进行删除。

执行下面的命令来查找root目录下十天之前创建或更改过的文件:

root@devops:~/osetc# find /root -mtime +10 -name "mysql-server*"
/root/mysql-server_5.7.20-1ubuntu16.04_amd64.deb-bundle.tar
/root/mysql-server_5.7.20-1ubuntu16.04_amd64.deb

下一步就可以使用rm命令对查找到的文件进行删除,执行下面的命令:

# find /root -mtime +10 -name "mysql-server*"  -exec rm -rf {} \;

当然也可以使用find命令的ctime参数。

Linux 通过rm()函数进行文件的删除

在linux系统里可以通过unlink和rmdir函数来进行文件的删除,但是rmdir函数只能删除空目录文件,所有我们需要新写一个函数来先删除目录文件下的所有文件,使其成为一个空目录,进而调用rmdir函数删除空目录。如果是普通文件的话,就可以通过unlink函数进行删除。 通过新函数rm来判断文件类型,目录文件通过rm_dir函数删除,普通文件通过unlink函数删除。

rm_dir函数如下:

//递归删除目录下的所有文件

int rm_dir(std::string dir_full_path)

{
DIR* dirp = opendir(dir_full_path.c_str());
if(!dirp)
{
return -1;
}

struct dirent *dir;
struct stat st;
while((dir = readdir(dirp)) != NULL)
{
if(strcmp(dir->d_name,".") == 0
|| strcmp(dir->d_name,"..") == 0)
{
continue;
}

std::string sub_path = dir_full_path + '/' + dir->d_name;
if(lstat(sub_path.c_str(),&st) == -1)
{
Log("rm_dir:lstat ",sub_path," error");
continue;
}
if(S_ISDIR(st.st_mode))
{
if(rm_dir(sub_path) == -1) // 如果是目录文件,递归删除
{
closedir(dirp);
return -1;
}
rmdir(sub_path.c_str());
}
else if(S_ISREG(st.st_mode))
{
unlink(sub_path.c_str());     // 如果是普通文件,则unlink
}
else
{
Log("rm_dir:st_mode ",sub_path," error");
continue;
}
}
if(rmdir(dir_full_path.c_str()) == -1)//delete dir itself.
{
closedir(dirp);
return -1;
}
closedir(dirp);
return 0;
}

Rm函数如下:

int rm(std::string file_name)
{
std::string file_path = file_name;
struct stat st;
if(lstat(file_path.c_str(),&st) == -1)
{
return -1;
}
if(S_ISREG(st.st_mode))
{
if(unlink(file_path.c_str()) == -1)
{
return -1;
}
}
else if(S_ISDIR(st.st_mode))
{
if(file_name == "." || file_name == "..")
{
return -1;
}
if(rm_dir(file_path) == -1)//删除目录下的所有文件.
{
return -1;
}
}
return 0;
}

Linux 删除文件后 空间没有释放

当Linux系统下的磁盘的使用空间达到100%后,我们肯定会对文件系统里的某些不用的文件或者比较大的日志文件进行清理,比如我们会删除apache服务的日志文件, 但是当我们通过rm命令删除掉日志文件后, 我们通过df命令查看当前磁盘的可用空间依旧没有变化,这是怎么回事呢? 为什么文件删除后,磁盘空间没有被释放?

磁盘空间没有被释放的原因如下

在Linux文件系统里,当我们通过rm命令将文件删除后,系统只会将文件的链接或者指针删除掉,但是数据并没有被从所占用的磁盘空间清除,而如果之前调用这个文件的进程依旧在运行的话,那么指针也不会被删除,因为该进行依然会写数据到该文件里,所以内核依然会认为该文件没有被删除。 所以当我们再次使用df命令查看磁盘空间的时候,空间使用率依旧没有变化。

磁盘空间没有被释放的解决方法:

其实解决办法很简单,那就是找到调用这个文件的进程,将该进程重新启动或者关闭,比如重新启动HTTP服务。当然还有万能的方法,那就是重启Linux系统。

对于不能重启系统或者进程的情况,我们可以通过对日志文件的写操作,对该文件进行重新覆盖,这样就会清空该文件所占用的存储空间。比如要清空HTTP的日志文件,我们可以执行下面的命令:

#echo “”> /tmp/access.log

Linux 删除文件恢复

通过上面的介绍,我们知道文件通过rm命令删除后,系统只是删除了执行该文件inode链接,但并没有删除文件的数据块。 我们可以通过proc文件系统来恢复删除的文件,因为每一个进程在proc文件系统里都会有一个目录和进程名字,里面会包含一个文件描述符子目录,该进程需要打开的所有文件链接都会在这个目录里。 所以当从文件系统里删除文件后,proc文件系统里依然还有一个inode的引用。

下面我们来演示将恢复删除后的/var/log/syslog 日志文件:

1# 删除日志文件/var/log/syslog, 执行下面的命令:

#rm /var/log/syslog

2# 通过lsof命令来查看进程的文件描述符和相关文件名信息,执行下面的命令:

# lsof | grep /var/log/syslog

命令输出如下:

root@devops:~/osetc# lsof | grep /var/log/syslog

lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs

Output information may be incomplete.

rsyslogd    972                syslog    5w      REG                8,1    24202    1311921 /var/log/syslog (deleted)

从上面的输出中可以看到进程的pid号为972

3# 进入proc文件系统查看进程号为972的文件描述信息,执行命令:

# ll /proc/972/fd/

命令输出如下:

root@devops:~/osetc# ll /proc/972/fd/
总用量 0
dr-x------ 2 root   root    0 3月  15 21:14 ./
dr-xr-xr-x 9 syslog syslog  0 3月  14 22:22 ../
lr-x------ 1 root   root   64 3月  15 21:14 0 -> /dev/null
l-wx------ 1 root   root   64 3月  15 21:14 1 -> /dev/null
l-wx------ 1 root   root   64 3月  15 21:14 2 -> /dev/null
lrwx------ 1 root   root   64 3月  15 21:14 3 -> socket:[13886]
lr-x------ 1 root   root   64 3月  15 21:14 4 -> /proc/kmsg
l-wx------ 1 root   root   64 3月  15 21:14  5 -> /var/log/syslog (deleted)
l-wx------ 1 root   root   64 3月  15 21:14 6 -> /var/log/auth.log
l-wx------ 1 root   root   64 3月  15 21:14 7 -> /var/log/kern.log

从输出里我们可以看到syslog文件的链接信息,可以通过head -5 命令来查看文件内容。

#head -5  /proc/972/fd/5

命令输出如下:

root@devops:~/osetc# head -5 /proc/972/fd/5
Mar 14 22:23:06 devops anacron[998]: Job `cron.daily' terminated
Mar 14 22:23:13 devops gnome-session[1826]: Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
Mar 14 22:27:15 devops anacron[998]: Job `cron.weekly' started
Mar 14 22:27:15 devops anacron[2837]: Updated timestamp for job `cron.weekly' to 2018-03-14
Mar 14 22:27:20 devops anacron[998]: Job `cron.weekly' terminated

4# 执行下面的命令,恢复syslog文件

#cat  /proc/972/fd/5 >/var/log/syslog

命令输出如下:

root@devops:~/osetc# cat /proc/972/fd/5 >/var/log/syslog

root@devops:~/osetc# ls /var/log/syslog
/var/log/syslog

我们可以看到被删除后的syslog文件已经被恢复了。

也可以参考本站的另一篇文章,实现linux系统下的回收站功能,进而更方便的实现删除文件的恢复。


99%的人还阅读了:

Linux下文本文件中^M 符号问题的解决

在linux下,不可避免的会用VIM打开一些windows下编辑过的文本文件。我们会发现文件的每行结尾都会有一个^M符号,这是因为 DOS下的编辑器和Linux编辑器对文件行末的回车符处理不一致,

对于回车符的定义:
windows:0D0A
unixlinux: 0A
MAC: 0D

比较快捷的去除这些符号的方法有这么几种:

(1)是用VI的命令:
使用vi打开文本文件
vi dos.txt
命令模式下输入

1
2
    :set fileformat=unix
    :w

(2) VI下使用正则表达式替换

1
   g/^M/s/^M//

或者

1
   %s/^M//g

(3)使用sed 工具

1
    sed ’s/^M//’ filename > tmp_filename

(4)既然window下的回车符多了‘ ’,那么当然通过删除‘ ’ ,也可以实现:
tr -d ” ”

(5)最后一个方法是本人最常用的方法,个人觉得最方便
在终端下敲命令:

1
   $ dos2unix filename

直接转换成unix格式,就OK了!~

vim /vi :如何在vim 编辑器里画图

如果你想在vim编辑器里也可以实现画简单的线性图,那么可以使用vim 里的一个叫 VIM Drawit!的插件。

下面来看看如何来安装vim drawit! 插件:
首先下载vim drawit! 安装包,输入下面的命令:

1
wget -O DrawIt.vba.gz http://www.vim.org/scripts/download_script.php?src_id=8798

安装vim drawit!插件
使用vim 命令编辑下载的vim drawit! 文件,在末行模式下输入下面的命令:

1
2
:so %
:q

vim 编辑器里 Drawit! 插件使用
\di 命令将会开启drawit! 插件
\ds 命令将会关闭drawit! 插件

举个例子:
使用vim drawit!插件画个导航图

使用上下左右键你可以用来画出方框或者方向线。
如下图:
如何在vim 编辑器里画图1

vi /vim:如何将光标跳转到文件末尾

当你用 vi /vim 编辑一个大文件的时候,如何能从当期行快速跳转到最后一行呢?

你可以使用下面的 vi / vim 的快捷键命令:

1
G

该命令会直接跳转到末尾行。

如果想在回到开始行的话,可以输入下面的命令:

1
1G

1
gg

 
更多参考:
1. Linux 下 vi/vim 文本编辑器超详细使用指南
2. 29个最基本的 vim /vi 命令
3. vim 命令大全 / vi 命令大全

Linux: vi / vim 字符串搜索和替换

在linux或者unix系统下,我们常常会用vi/vim命令打开一个文件,并在文件里查找特定的字符串,也有可能会将找到的字符串替换成另一个字符串。
vi/vim
 
vi /vim 命令字符串搜索并替换的命令格式如下:

1
%s/old/new/

 
vi /vim 命令字符串搜索并替换例子
查找字符串“oldtest”并将其替换成”newtest”,在vim 末行模式下输入命令:

1
:$s/oldtest/newtest/

 
上面的命令只会替换所有行里发现的第一个匹配的字符串。

如果你想替换文本所有匹配的字符串,可以使用下面的命令:

1
:%s/oldtest/newtest/g

 
vi/vim命令限定范围查找并替换字符串
如果你只想将从第10行到第20行的文本行中的查找并替换字符串,那么可以输入下面的命令:

1
:10,20s/oldtest/newtest/

 
更多参考:
1. Linux 下 vi/vim 文本编辑器超详细使用指南
2. 29个最基本的 vim /vi 命令
3. vim 命令大全 / vi 命令大全

vi / vim: 如何在打开文件的时候直接跳转到指定的函数或行

当使用linux 下vi /vim命令打开文件后,你肯定想直接跳转到某个特定的函数或者字符串或者某行。如何来做?

你可以使用下面的命令来实现:
vi +<函数名> <要打开的文件名>


vi +<行号> <要打开的文件名>

例子:打开文件后直接跳转到第五行,输入下面的命令:

1
vim +5 foo.txt

输出如下:
vim 如何在打开文件的时候直接跳转到指定的函数或行1

打开文件后直接跳转当特定的函数,输入下面的命令:

1
vim +/pathmunge /etc/profile

命令输出:

vim 如何在打开文件的时候直接跳转到指定的函数或行1

 
更多参考:
1. Linux 下 vi/vim 文本编辑器超详细使用指南
2. 29个最基本的 vim /vi 命令
3. vim 命令大全 / vi 命令大全

常用 vi / vim 快捷键命令总结

当你在使用vim命令编辑一个文件的时候,会用到很多的快捷键操作,比如拷贝一整行,拷贝多行文本等。。

vi/vim
#1 拷贝整行文本

1
yy

1
shift y

1
:ny

#2 拷贝从光标位置开始到行尾的字符串

1
y$

#3 拷贝当前行之后的三行内容

1
3yy

#4 拷贝一个范围的文本行

1
1,5y

1
1y5

#5 删除一整行

1
dd

1
:nd

#6 删除从光标处到行末的所有字符串

1
d$

1
shift d

#7 删除多行文本

1
:1,5d

1
1d 5

#8 将vim切换到替换模式

1
shift r

#9 撤销操作

1
u

#10 重做操作

1
ctrl r

解决ubuntu下vim “E319:命令不可用”问题

在ubuntu linux 系统下,但使用vim 命令打开一个文件后,如果你输入 vim 命令:syntax on 来开启代码高亮显示的时候,会遇到下面的E319问题。
E319: Sorry, the command is not available in this version: syntax on

如何来解决这个问题呢?
你需要重新安装完整版的vim版本,输入下面的命令:

1
sudo apt-get install vim

VI / VIM 里如何显示行号

当使用vi /vim 查看或编辑文件的时候,如何显示每行的行号呢。
首先要进入末行模式,使用ESC键,然后输入下面的命令:

1
set number

看下图:
VIM 里如何显示行号