文本替换
命令行批量替换多文件中的字符串,常用有三种方法:Mahuinan 法、Sumly 法和 30T 法。
----- 查看所匹配的字符串
$ sed -n '/orig/'p *.txt
----- Mahuinan法,用sed命令批量替换多个文件中的字符串
$ sed -i "s/orig/sub/g" "`grep orig -rl directory`"
解读:
sed -i 选项表示原地替换,若只显示结果则用-e替换;
g 表示全局,否则只替换第一个匹配字符串;
grep -r 表示对目录递归调用;-l(L小写)列出匹配的文件。
----- Sumly法
$ perl -pi -e "s/China/Sumly/g" /www/*.htm /www/*.txt
解读:
将www文件夹下所有的htm和txt文件中的"China"都替换为"Sumly"
----- 30T法
$ perl -pi -e 's/baidu/30T/g' `find /www -type f`
解读:
将www文件夹下所有文件,不分扩展名,所有的"baidu"都替换为"30T"
注意,在 Mahuinan 中,为了防止文件名中存在空格,所以使用引号包裹。
install 和 cp 命令
两者都可以将文件/目录拷贝到指定的目录,不过 install 允许你控制目标文件的属性,常用于程序的 Makefile 文件。
install [OPTION]... SOURCE DIRECTORY
常用参数:
-m, --mode=0700
设定权限;
-v, --verbose
打印处理的每个文件/目录名称;
-d, --directory
所有参数都作为目录处理,而且会创建指定目录;
-g, --group=mysql
设定所属组,而不是进程目前的所属组;
-o, --owner=mysql
设定所有者,只适用于超级用户;
-s, --strip
使用strip命令删除文件中的符号表 (symbol table);
-S, --suffix=exe
指定安装文件的后缀;
-p, --preserve-timestamps
以源文件的访问/修改时间作为相应的目的地文件的时间属性;
-t, --target-directory
如果最后一个文件是一个目录并且没有使用-T,--no-target-directory选项,
则将每个源文件拷贝到指定的目录,源和目标文件名相同;
使用 -d
选项时,如果指定安装位置为 /usr/local/foo/bar
,一般 /usr/local
已存在,install 会直接创建 foo/bar
目录,并把程序安装到指定位置。
如果指定了两个文件名,则将第一个文件拷贝到第二个,
----- 安装目录,等价于mkdir /tmp/bin
$ install --verbose -d -m 0755 /tmp/bin
----- 安装文件,等价于cp a/e c
$ install -v -m 0755 a/e c
----- 安装文件,等价于mkdir -p a/b && cp x a/b/c
$ install -v -m 0755 -D x a/b/c
避免误删目录
今天就来聊聊 linux 下一个常见的问题:如何避免误删目录。下文会详细的讲述不同的场景下误删目录,以及相应的解决方案。
#--- 1. 变量为空导致误删文件,如果file为空或命令返回空
rm -rf /usr/sbin/$file
#--- 使用变量扩展功能,变量为空使用默认值或抛出异常退出
rm -rf /usr/sbin/${file:?var is empty}
#--- 人肉判断变量是否为空
[[ ${file} == "" ]] && echo 1
[[ -z ${file} ]] && echo 1
#--- 2. 路径含有空格导致误删文件
path="/usr/local /sbin"
rm -rf $path
#--- 变量加引号防止扩展
rm -rf "$path"
#--- 3. 目录或文件含有特殊字符导致误删文件,例如 "~"
#--- 变量加引号防止扩展
rm -rf "~"
#--- 4. cd切换目录失败,导致文件被误删
#--- 使用逻辑短路操作
cd path && rm -rf *.exe
#--- 检测path是否存在
[[ -d path ]] && echo 1
man
Linux 上的 manpage 是用 groff 语法编写的,实际上可以通过如下的命令查看:
zcat man.1.gz | groff -man -Tascii | more
其查找路径可以通过 man -w
命令查看,或者查看配置文件 /etc/man.config
;很多帮助文档保存在 /usr/share/man
目录下,又按照不同类型保存不同的子目录下,例如 /usr/share/man/man1/mysqlshow.1.gz
。
如下是常见的查看命令:
----- 查看搜索路径
$ man -w
----- 显示man命令搜索到的第一个文件路径
$ man -w passwd
----- 显示所有匹配的man文档
$ man -aw passwd
----- 指定领域限制
$ man 5 passwd
$ man -S 1:2 passwd
----- 同命令whatis ,将在whatis数据库查找以关键字开同的帮助索引信息
$ man -f httpd
----- 同命令apropos 将搜索whatis数据库,模糊查找关键字
$ man -k httpd
换行处理
*nix 系统里,每行结尾只有 "<换行>"
,即 "\n"
;Windows 系统里面,每行结尾是 "<换行><回车>"
,即 "\n\r"
。
如果不进行转换,那么 *nix 系统下的文件在 Windows 里打开所有文字会变成一行;而 Windows 里的文件在 *nix 下打开的话,在每行的结尾可能会多出一个 ^M
符号。
要把文件转换一下,有两种方法:
- 命令
dos2unix test.file
; - 去掉
"\r"
,用命令sed -i 's/\r//' test.file
。
历史命令
----- 去除重复命令,包括不连续的命令,通过ignoredups去除连续重复的命令
export HISTCONTROL=erasedups
异常处理
Text file busy
执行复制时可能会报如上的错误,处理方式如下:
----- 查看文件被那个进程占用
# fuser youfile
如果有进程占用,确保进程无用直接 kill
掉。
杂项
shell 操作
----- 查看当前所有shell
$ chsh -l
$ cat /etc/shells
查看当前的 Shell ,可以查看 SHELL
变量,不过如果是通过 bash dash sh 等直接运行的话,那么 SHELL 不变,可以通过如下方式查看。
$ ps | grep $$ | awk '{print $4}'
$ echo $0
$ tom # 输入没有的命令
chsh -s /bin/dash
实际修改的是 /etc/passwd
文件里和你的用户名相对应的那一行,重启 Shell 后即可。
符号链接
当读取符号链接文件时,默认会重定向到指定的文件,可以通过 C 中的 readlink()
或者 readlink
命令查看符号链接文件中的内容。
----- 建立测试用符号链接
$ echo "just for test" > original.txt
$ ln -s original.txt symbol.txt
----- 读取并解析出源文件的绝对路径
$ readlink -f symbol.txt
----- 直接查看符号链接的内容
$ readlink symbol.txt
----- 复制时保持符号链接内容
$ cp -d symbol.txt copy.txt
硬链接
通过 ls -l
可以查看符号链接所引用的原文件,而对于硬链接则不能通过上述命令查看,可以通过如下方式查看所有的硬链接文件。
----- 查找文件对应的inode信息,包括其引用计数
$ ls -il
----- 根据inode信息找到所有的文件
$ find / -inum 33582147
注意:软链接能够跨越文件系统 (分区),硬链接不可以。