Linux 文件命令

文件与目录

witch

没有这个 witch (巫婆) 命令啦,老是将 which (哪一个) 打成 witch。
那卡住了怎么办? ls 应该记得起来吧,另再记两个目录 /bin/usr/bin

$ls \bin\w*
ls: cannot access 'binw*': No such file or directory
又打错了,改成斜线 (/)。
$ls /bin/w*
/bin/wdctl  /bin/which  /bin/whiptail

好!看到了 which 是在 /bin/which

/bin/which 去找 which
/bin/which which
/usr/bin/which

疑?用 /bin/which 去找 which 结果是 /usr/bin/which

看一下 path
$echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

原来运行 which 时是按 path 搜索,先找 /usr/bin 再找 /bin,缺省行为是找到后就不再继续运行。

which 有没有可以找出全部的 path 的参数?
$which -h
Illegal option -h
Usage: /usr/bin/which [-a] args
$which --help
Illegal option -h
Usage: /usr/bin/which [-a] args
好吧!应该就是 -a 吧,一个说明都要这么省。
which -a which
找到了两个路径
/usr/bin/which
/bin/which
列示 /usr/bin/which
$ls /usr/bin/which -l
lrwxrwxrwx 1 root root 10 2019-10-21 13:23 /usr/bin/which -> /bin/which

/usr/bin/which 是链接至 /bin/which,不过这里有点疑问,linux 已经把 /bin 纳入 PATH 了, 不知道为什么还要在 /usr/bin 做链接,也许是要让学习 linux 困难一点?

journalctl 这个命令这么长,老是忘记,来一个 ls 吧!
$ls /bin/j*
/bin/journalctl
journalctl 又有链接? 幸好没有,要不然全乱了。
$which -a journalctl
/bin/journalctl

which 太方便了,好吧!建一个 Windows which。

which.cmd
@setlocal
@set P2=.;%PATH%
@for %%e in (%PATHEXT%) do @for %%i in (%~n1%%e) do @if NOT "%%~$P2:i"=="" echo %%~$P2:i

不过也不需要啦,Windows 用 where 即可。

ls 查看目录与文件

ls [选项] [文件或目录]
ls 选项

-l

以每行列出详细数据

-h, --human-readable

以高可读性显示文件容量大小 (如 1K 2M 3G)。

-a, --all

显示所有文件,含隐藏档。

-A, --almost-all

显示所有文件,但不包括 ... 这两个目录。

-d, --directory

列出该目录而不是目录内的文件。

-R, --recursive

递归,含目录内的所有文件。

-r, --reverse

排序时倒序。

-t

依时间排序。

-S

依文件容量大小排序。

-F, --classify

加入指示字符,如将目录后置 /

-i, --inode

列出实际保存于文件系统中的索引码,可参阅后文的硬链接

设置 ls 显示时间格式 long-iso,显示时间格式如为 2038-01-19 03:47。
export TIME_STYLE=long-iso
处理目录内 .txt 的范例
for F in $(ls *.txt); do \
echo $F; \
done

cp 拷贝

cp [参数] 来源 目的
cp 选项

-r, -R

递归,含目录内的所有文件。

-p

拷贝文件 (或目录) 的拥有者及群组 (ownership),文件权限 (mode) 及时间 (timestamps),拥有者及群组仅限超级用户 (即为 root) 才会拷贝。

-d

保留文件链接 (跟 --no-dereference --preserve=links 相同)。

--preserve=links

保留文件链接。

--preserve=all

连同特殊属性 (拥有者、群组、文件权限、时间、链接、xattr) 一并拷贝,拥有者及群组仅限超级用户 (即为 root) 才会正确。

-a

-dR--preserve=all 相同

-L, --dereference

拷贝链接档的实际文件。

-P, --no-dereference

拷贝软链接 (never follow symbolic links in SOURCE)。

--parents

保留来源目录结构。

-f, --force

强制运行,在无法写入目的文件时,尝试删除目的文件后,再次重新拷贝 (同时具有 -n 选项时,本选项将被忽略)。

--remove-destination

先删除目的文件,再运行拷贝。

-n, --no-clobber

不要覆盖现有的文件。

-i, --interactive

在覆盖文件之前,先询问。

-u, --update

更新,当来源比「目的」新或「目的」缺少才会拷贝。

-l, --link

将文件拷贝成硬链接。

-s, --symbolic-link

将文件拷贝成软链接。

-S, --suffix=SUFFIX

指定备份档的结尾名称,未指定为 ~

-b, --backup

备份目的文件 (若目的文件已存在,将目的文件名增加结尾名称,如果结尾名称的文件已存在,先删除再改名)。

基本操作
文件拷贝
cp 来源文件 目的文件
将文件拷贝到其他目录,可指定目的目录 (保留源文件案名称)
cp 来源文件 已存在的目的目录/
多档拷贝
cp 来源档1 来源档2 来源档3 已存在的目的目录/
拷贝目录
cp -r /path/folder 添加的目的目录

当目的目录不存在时则拷贝至该目的目录。
但如果目的目录存在则拷贝至该目录内,递归拷贝目录内容,需在来源目录后增加一个 * (通配字符)。

递归拷贝目录内容
cp -r /path/folder/* 已存在的目的目录 (1)
1 /path/folder/* 改为 /path/folder/,则拷贝至 已存在的目的目录/folder
cp 缺省行为
  • 拥有者及群组 (ownership) 权限为操作帐户。

  • 拷贝文件权限 (mode)

  • 将硬链接转成一般文件。

  • 拷贝软链接。

  • 覆盖文件且不会询问。

  • 不会删除目的目录的多余文件。

不要覆盖现有的文件
不要覆盖现有的文件 -n,文件已存在,并不会运行拷贝。
cp -n source.txt dest.txt
或者在覆盖文件之前,先询问 -i
$cp -i source.txt dest.txt
cp: overwrite 'dest.txt'?
更新文件 (-u),来源文件的修改时间比目的文件还新,或者目的文件缺少,则更新文件
cp -u source.txt dest.txt
-iur 来得知目录内那些文件需要更新
$cp -iur source/*  dest
cp: overwrite 'dest/source.txt'?
强制覆盖文件
如果目的文件文件无法写入(如权限为唯读),则无法运行拷贝。
$cp soruce.txt dest.txt
cp: cannot create regular file 'dest.txt': Permission denied
-f 强制运行
cp -f soruce.txt dest.txt
--remove-destination 先删除目的文件,再运行拷贝。
cp --remove-destination soruce.txt dest.txt
备份目的文件

覆盖目的文件时,若需备份可采用 -b 备份目的文件。

备份目的文件 -b
cp -b source.txt dest.txt

缺省会将目的文件的结尾名称加上 ~,例如 dest.txt 会备份至 (改名为) dest.txt~,如果 dest.txt~ 已存在,则先删除 dest.txt~ 再将 dest.txt 改名。指定备份结尾文件名以 -S 来设置。

指定备份目的文件 -S .bak
cp -b -S .bak source.txt dest.txt

dest.txt 则备份至 dest.txt.bak,如果 dest.txt.bak 已存在,则先删除 dest.txt.bak 再将 dest.txt 改名。

拷贝链接文件

拷贝文件时,拷贝连接文件的目标文件,可采用 -L 拷贝链接档的目标文件,拷贝后为一般文件。
link.txt 是指向 source.txt 的链接档,dest.txt 实际上是拷贝 source.txt

-L 拷贝链接档的目标文件。
cp -L link.txt dest.txt

在拷贝软链接文件时,将软链接直接拷贝,可采用 -P 拷贝软链接,如 soft-link 是一个软链接,拷贝后的 dest.txt 亦为软链接文件。

这里为什么要强调是链接?
因为硬链接会拷贝成一般文件。

-P 拷贝软链接
cp  -P soft-link.txt dest.txt

保留文件链接 -d 的情况比较复杂,当硬链接的目标文件在相同的目录一起被拷贝时,则以硬链接拷贝,其他情况则转成一般文件。
如在 source 目录内,文件 source.txt 的硬链接为 link.txt,在目录中创建硬链接 other-link.txt 链接至 other/source.txt

列出测试目录的内容
$ls other source -liU
other:
total 4
2935287 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 source.txt

source:
total 12
2935287 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 other-link.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 source.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 link.txt
以保留文件链接 -d,将目录 source 拷贝至目录 dest
$cp -rd source dest

$ls dest/source.txt dest/link.txt dest/other-link.txt -liU
2935289 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 13:43 dest/source.txt (1)
2935289 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 13:43 dest/link.txt (1)
2935290 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 13:43 dest/other-link.txt (2)
1 硬链接的源文件一起被拷贝,则会以硬链接拷贝。
2 不在相同的目录则会转成一般文件。
以参数 -d 拷贝 dest/link.txtdest/dest.txtdest/dest.txt 视为一般文件。
$cp -d dest/link.txt dest/dest.txt

$ls dest/dest.txt -li
2935291 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 14:42 dest/dest.txt
以软、硬链接拷贝文件

以参数 -s 将文件拷贝成软链接,等同于 ln -s 命令创建链接,link.txt 是一个指向 source.txt 的链接档。

将文件拷贝成软链接 -s
cp -s source.txt link.txt

以参数 -l 将文件拷贝成硬链接,等同于 ln 命令创建链接,link.txtsource.txt 的分身 (inode 相同)。

将文件拷贝成硬链接 -l
cp -l source.txt link.txt
cp 创建链接比 ln 的好处是可一次创建目录下多个链接。
cp -sr $PWD/source soft-dest
cp -lr source hard-dest
拷贝拥有者及群组、文件权限及时间

拷贝拥有者、群组、文件权限及时间 -p-a,以超级用户 (即为 root) 运作时,拥有者及群组权限才会拷贝。

拷贝文件权限及时间 -p
sudo cp -p source.txt dest.txt
拷贝文件权限及时间及保留链接 -a
sudo cp -a source.txt dest.txt
保留来源目录结构
--parents 保留来源目录结构。
mkdir -p path/to
touch path/to/source.txt
mkdir dir-parents

cp --parents path/to/source.txt dir-parents/
$tree path (1)
path
└── to
    └── source.txt

$tree dir-parents
dir-parents
└── path
    └── to
        └── source.txt
1 若没有 tree 命令,以 sudo apt install tree 安装。

scp 安全拷贝远程目录与文件

scp 是 secure copy 的缩写,基于 ssh 安全通信拷贝远程的文件 (目录)。

scp 命令的语法跟 cp 类似,scp 可在主机之间拷贝文件,其语法为:
scp [[来源帐号@]来源主机:]来源文件或目录 [[目的帐号@]目的主机:]目的文件或目录

省略帐号与主机,表示本机的文件,只省略帐号表示本地端的用户帐号跟远程帐号一样。

scp 选项

-r

递归,含目录内的所有文件。

-p

保留文件时间

-C

压缩之后再发送

-l

限制网络带宽,单位为 Kbit/s。

-p

拷贝源文件案的修改时间、访问时间和文件权限 (mode)。

基本操作

ubuntu 帐号登录 192.168.1.1 主机,将主机上的 /path/file 拷贝到本地端的 /path/file
本地端的用户帐号跟远程的用户帐号一样时,可省略用户帐号。

从远程文件拷贝到本地端
scp ubuntu@192.168.1.1:/path/file /path/file
在运行命令时,会以 SSH 登录远程的主机,需输入 ubuntu@192.168.1.1 的密码 (公开密钥连接 SSH 服务器除外):
ubuntu@192.168.1.1's password:
从远程文件拷贝到本地端,省略帐号
scp 192.168.1.1:/path/file /path/file

拷贝方向相反也类似。

由本地端文件拷贝到远程
scp /path/file 192.168.1.1:/path/file
从远程目录拷贝到本地端
scp -r 192.168.1.1:/path/folder 添加的目的目录

当目的目录不存在时则拷贝至该目的目录。
但如果目的目录存在则拷贝至该目录内,递归拷贝目录内容,需在来源目录后增加一个 * (通配字符)。

递归拷贝目录内容
scp -r 192.168.1.1:/path/folder/* 已存在的目的目录 (1)
1 若把 /path/folder/* 改成 /path/folder/,则拷贝至 已存在的目的目录/folder
拷贝文件权限 (mode) 及时间 -p
scp -p 192.168.1.1:/path/file /path/file
限制传输速度为 100 Kbit/s
scp -l 100 192.168.1.1:/path/file /path/file (1)
1 -l 跟数字之间,可不需要空白字符。
将数据压缩之后再发送 -C
scp -C 192.168.1.1:/path/file /path/file
SSH 服务的连接端口号为 22,改为自订连接端口 222。
scp -P 222 192.168.1.1:/path/file /path/file

rm (删除)、mv (移动或改名)

rm
rm 移除的文件或目录
rm 选项

-r, -R

递归,含目录内的所有文件。

-f

强制删除不会询问。

mv
mv 移动(或改名)来源 目的

mv 是 move 的缩写,除了移动的功能外也可以重命名。将「来源」移动至「目的」,如果「目的」为存在的文件则会被覆盖。

ln 文件链接

通过链接文件,不同的文件名可以指向同一个文件。链接类型分为硬链接 (hard link) 和符号链接 (symbolic link) 两种,符号链接也称软链接 (soft link),缺省的链接类型是硬链接。

软链接

软链接为一个独立的文件或目录,类似于 Windows 操作系统中的快捷方式方式。
软链接本身有文件属性及权限。
软链接可以跨文件系统。
软链接可以对目录进行链接。
删除软链接并不影响目标文件,若目标文件被删除,则相关软链接被称为已断开的悬挂链接 (dangling link),当重新创建目标时则悬挂链接可恢复为正常。
创建不存在目标的软链接 (跟悬挂链接相似),不会提示错误 (注:ls 会将指向显示成红色)。
绝对路径所创建的链接档,在搬移软链接档时目标位置会相同,而以相对路径创建的链接档,其目标位置则会变动。

ln 语法
ln [参数] 目标(TARGET) 链接名称(LINK_NAME)

本文中将「链接名称」指向的文件 (或目录) 称为「目标」。
「链接名称」为「软链接」或「硬链接」。

ln 选项

-s, --symbolic

创建软链接。

-r, --relative

创建相对路径的软链接。

-P, --physical

创建成硬链接 (默认值,不需指定本参数)。

-f, --force

强制运行 (链接存在时先删除文件)。

-i, --interactive

交互模式,链接存在时提示是否取代。

-S, --suffix=SUFFIX

指定备份文件名的结尾名称,未指定为 ~

-b, --backup

备份链接文件 (若链接文件已存在,将链接文件名增加结尾名称,如果结尾名称的文件已存在,先删除再改名)。

-v, --verbose

显示详细的处理过程

创建软链接

以参数 -s,将 source.txt 创建 softlink.txt 软链接档。

创建软链接 -s
ln -s source.txt softlink.txt

链接至不同目录,创建的「目标」是相对于「链接名称」的路𠇹。

source 目录中创建一个 source.txt 文件,并创建一个 dest 目录
mkdir source
echo 123 > source/source.txt
mkdir dest
dest 目录中,创建相对路径目标 ../source/source.txt 的软链接 RelLink1.txt
cd dest
ln -s ../source/source.txt RelLink1.txt

在目录中,创建的目标很直觉会采用正确的相对路径。
但如果在目录外往往会出错。

创建错误的软链接 ErrorLink.txt
cd ..
ln -s  source/source.txt dest/ErrorLink.txt
正确的「目标」是「链接名称」位置的相对路𠇹 (当做目前路径是「链接名称」的目录内)。
ln -s ../source/source.txt dest/RelLink2.txt
或者以 -r 创建相对路径的软链接。
ln -sr source/source.txt dest/RelLink3.txt
创建绝对路径的 AbsLink.txt
ln -s $PWD/source/source.txt dest/AbsLink.txt
显示 dest 目录内置立的软链接文件。
$ls dest -li
total 0
2906099 lrwxrwxrwx 1 ubuntu ubuntu 35 2023-03-12 20:32 AbsLink.txt -> /home/ubuntu/demo/source/source.txt
2893916 lrwxrwxrwx 1 ubuntu ubuntu 17 2023-03-12 20:31 ErrorLink.txt -> source/source.txt
2893902 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:31 RelLink1.txt -> ../source/source.txt
2894388 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:31 RelLink2.txt -> ../source/source.txt
2894401 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:32 RelLink3.txt -> ../source/source.txt
创建硬链接
创建目标为 source/source.txtdest/HardLink.txt 硬链接
ln -P source/source.txt dest/HardLink.txt (1)
1 -P 为默认值,可不需要该参数。

硬链接是使用相同的 inode,没有相对路径的问题。

显示 source/source.txt dest/HardLink.txt 的 inode
$ls source/source.txt dest/HardLink.txt -lU --inode
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 20:05 source/source.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 20:05 dest/HardLink.txt

两个不同文件,实际保存于文件系统中的索引码 (inode) 为 2935285,在文件权限后面的数字 2 表示该文件有 2 个硬链接。

删除硬连接 (应该说删除其中一个分身)
$rm source/source.txt (1)

$ls dest/HardLink.txt -lU --inode
2935285 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 21:05 dest/HardLink.txt
1 或者以 unlink 删除连接,运行 unlink source/source.txt

删除 source/source.txt 后,前面范例的软连接已变成了悬挂链接 (dangling link)。
删除 (以 rmunlink) dest/HardLink.txt 后,由于文件实体没有分身,则为实际删除该文件。

重建 source/source,回复原始状态。
$ln dest/HardLink.txt source/source.txt

$ls source/source.txt dest/HardLink.txt -lU --inode
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 21:05 source/source.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 21:05 dest/HardLink.txt

find 找出合乎模式的文件

搜索目录之下合乎条件的文件或目录。
find [path…​] [expression],expression 包含了林林总总的各式参数,全部混在一起。

find --help
find ... [path...] [expression]
expression may consist of: operators, options, tests, and actions

operators ...
      EXPR1 -o EXPR2   EXPR1 -or EXPR2   EXPR1 , EXPR2

normal options (在其他参数之前先指定 options):
      -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf

tests ...
      -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN

actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print

find 的参数有不少,可用 man find 取得详细说明。

tests (测试参数)
名称符合

-name PATTERN: 文件名称符合 PATTERN,-iname 不区分大小写。
-path PATTERN: 目录名称符合 PATTERN,-ipath 不区分大小写。
目录名称包含了 / (斜线),如 -ipath '*/some-path/*' 表示找出目录名称 some-path 的文件,而 -ipath '*/some*/*' 则找出目录名称前置 some

文件、目录名称符合 PATTERN 的外框需加单引号 (') 或双引号 (")。否则;要转译正规表示法的特殊字符'*.txt' 要转译成 \*\.txt
文件类型符合

-type [bcdpflsD]: 类型参数 f 文件,l 链接档,d 目录…​ 。

文件时间符合

-amin 读取分钟,-atime 读取天数,-cmin 修改分钟,-ctime 修改天数
-ctime n: 文件在 n 天前修改过。
-ctime +1: +n 大于 n,所以是 2 天前修改过。
-ctime -n: 「减」表示跟目前的时间比较,在最近的 n 天内修改过的文件。

文件大小符合

-size +10M -size -20M,大于 10M 小于 20M 文件。单位:k Kilobytes,M Megabytes,G Gigabytes。

测试参数可不少直接查阅 find --help,像找出拥有者 -user,拥有群组 -group,文件权限 -perm。

找出目前路径及子路径内的 .txt 文件
find . -iname '*.txt' (1)
1 目前路径可以不输入 .
operators (表达式)
-a-and

AND (及) 逻辑,可不需要该表达式,expr1 -a expr2expr1 expr2 相同

找出最近一分钟修改的 .txt
find -iname '*.txt' -a -cmin -1
find -iname '*.txt' -cmin -1
-o-or

OR (或) 逻辑

找出 .txt 或 .doc 文件:
find -iname '*.txt' -o -iname '*.doc'

找出 .txt 或 .doc 文件,以长格式显示:
find -iname '*.txt' -ls -o -iname '*.doc' -ls

当表达式同时有 AND、NOT、OR 时,AND、NOT 先判断之后再判断 OR。
如果 OR 两边有相同条件,两边都要加入;另外 actions 也一样两边都要加入。

!-not

NOT (否定) 逻辑

找出不为 .txt 的文件:
find ! -name '*.txt'

找出拥有者不为 www-data 的文件:
find ! -user 'www-data'

找出文件权限不为 775 或目录权限不为 775:
find -type f -not -perm 775 -o -type d -not -perm 775
find -type f -not -perm 775 -ls -o -type d -not -perm 775 -ls
actions (动作)
find -iname '.log' -ctime 7 -delete (1)
find -iname '.log' -ctime -7 -ls (2)
1 删除 7 天前 .log 文件
2 以长格式列出 7 天内的 .log 文件
-exec 运行命令语法格式
  • -exec 命令 {} \;

  • -exec 命令 {} +
    先 (前置) 输出文件名称,再运行命令。

其中的字符串 {} 会替换成文件名称。

找出 7 天内有 error 记录的 .log 文件
find -iname '.log' -ctime -7 -exec grep error {} \;
find -iname '.log' -ctime -7 -exec grep error {} +
options (选项)

-maxdepth LEVELS,最大阶层。
-mindepth LEVELS,最小阶层。
注:options 需要在其他参数之前先指定。

找出目前路径的 .txt 文件
find . -maxdepth 1 -iname '*.txt'

rsync 远程同步文件与目录

rsync 主要用于同步 (镜像) 文件与目录,传输时比对内容仅拷贝差异文件,可减少数据传输量。
可保留文件的拥有者、群组与权限设置,删除多余的目的文件或目录。

安装 rsync
apt install rsync
rsync 语法
rsync [[来源帐号@]来源主机:]来源文件或目录 [[目的帐号@]目的主机:]目的文件或目录

省略帐号与主机,表示本机的文件,只省略帐号表示本地端的用户帐号跟远程帐号一样。

rsync 参数说明

--archive, -a

备份模式;递归备份所有子目录下的目录与文件,保留链接档、文件的拥有者及群组 (ownership)、文件权限 (mode) 以及时间戳记,跟 -rlptgoD 相同。
拥有者及群组仅限超级用户 (即为 root) 才会同步。

--recursive, -r

递归,含目录内的所有文件。

--links, -l

保留软链接。

--perms, -p

保留文件权限 (mode)。

--times, -t

保持时间戳记。

--group, -g

保留拥有群组 (仅限超级用户,即为 root)。

--owner, -o

保留拥有者 (仅限超级用户,即为 root)。

-D

same as --devices --specials

--devices

preserve device files (仅限超级用户,即为 root)。

--specials

preserve special files.

参数 -a 有不少 (以上) 功能,而且是最重要的参数,可以说是必备参数,如果没有该参数要花很多时间测试。

--hard-links, -H

保留硬链接。

--verbose, -v

详细模式输出。

--human-readable, -h

以可读性较高的方式来显示 (需配合 -v)。

--prune-empty-dirs, -m

不拷贝空目录。

--compress, -z

传输过程中压缩文件。

--dry-run, -n

测试运行。

--delete

删除多余的目的文件或目录。

--chmod

设置文件或目录权限,如 --chmod=775

--chown

设置拥有者及群组,如 --chown=www-data:www-data

--info=progress2

传输时以单行显总体进度 (man rsync)。

--itemize-changes, -i

显示每个文件的变动摘要。

--rsh=COMMAND, -e

设置远程登录指令。

--bwlimit=RATE

限制网络带宽,RATE 可指定如 1.5m,未指定单位时如 100,则为 100K。

基本操作
同步文件,将文件 file 同步至 dest/file,会自动创建 dest 目录。
rsync -a /path/to/file dest/
同步目录,将目录 d1 同步至 d2/d1,会自动创建 d2 目录。
rsync -a /path/to/d1 d2

若需将目录 d1 同步至目录 d2,同步目录内容需在来源目录后增加 / (斜线) 或是 /* (斜线及通配字符)。
当需要目录拷贝 (同步) 至目录时,可采用 rsync 并在来源目录增加 /,不管目的目录是否存在,只会拷贝至目的目录。

同步来源目录内容,将目录 d1 同步至目录 d2,会自动创建 d2 目录。
rsync -a /path/to/d1/ d2
rsync -a /path/to/d1/* d2

ubuntu 帐号登录 192.168.1.1 主机,将主机上的 /path/folder 拷贝到本地端的 dest
本地端的用户帐号跟远程的用户帐号一样时,可省略用户帐号。
可增加 -z 参数,将数据压缩后再传输,减少网络传输的数据量。

从远程目录同步到本地端
rsync -az ubuntu@192.168.1.1:/path/folder/ dest
在运行命令时,会以 SSH 登录远程的主机,需输入 ubuntu@192.168.1.1 的密码 (公开密钥连接 SSH 服务器除外):
ubuntu@192.168.1.1's password:
同步拥有者及群组、文件权限

-a 已经具备了该功能,以超级用户 (即为 root) 运行 rsync 时则能同步。

同步本地目录文件用户权限
sudo rsync -a /path/to/d1/ d2
ubuntu 同步远程目录
rsync -az /path/to/folder/ ubuntu@192.168.1.1:/path/to/folder
同步远程帐户为 ubuntu,若目的已存在而拥有者及群组不为 ubuntu 时则会引发错误,如下
rsync: failed to set permissions
rsync: failed to modify permissions
rsync: failed to set times on
远程帐户为 root,远程目的文件或目录的拥有者会同步。
rsync -az /path/to/folder/ root@192.168.1.1:/path/to/folder
同步时指定目的权限为 775,拥有者及群组为 www-data:www-data
rsync -az --chmod=775 --chown=www-data:www-data /path/to/folder/ root@192.168.1.1:/path/to/folder
当本地的文件权限超出了登录帐户权限,而以 sudo 运行时,也表示远程帐户也需要以 root 帐户登录,那么可不需要「目的帐号」。
sudo rsync -az /path/to/folder/ 192.168.1.1:/path/to/folder
显示文件变动摘要 (--itemize-change-i)
$rsync --itemize-change -a /path/to/d1 d2
.d..tp..... ./
>f+++++++++ f1.txt
>f..tp..... fh1.txt
>f..tp..... fh2.txt
cL+++++++++ fs1.txt -> f1.txt
cL+++++++++ fs2.txt -> ../d2/f2.txt
>f..t...... r1.txt

文件项目之前会多出 11 个字符,分别为 YXcstpoguax
意义如下:

Y 异动类型

<

文件发送至远程

>

本地端接收文件

c

代表本地端变动(如创建目录、软链接)

h

代表本地端创建硬链接(hard link)

.

代表没有变动(但可能有变动其他属性)

*

代表其余字段有包含消息(例如 deleting)

X 文件型态

f

一般文件

d

目录

L

软链接档

D

设备档(device)

S

特殊文件(如 sockets 或 fifo)。

cstpoguax 说明

c

内容变更。

s

大小变更。

t

时间戳记变更。

o

拥有者变更。

p

文件权限 (mode) 变更。

g

群组变更。

u

保留字段。

a

ACL 变更。

x

扩充属性(extended attribute)变更。

其他值

.

无变更

+

添加文件或目录

YXcstpoguax 示例
.d..t......

. 项目没有变动(尽管它变更了其他属性)
d 目录类型
t 时间变更

>f.st......

> 接收文件
f 一般文件
s 大小变更
t 时间变更

cd+++++++++

c 创建目录
d 目录类型
+++++++++ 添加目录

>f+++++++++

> 接收文件
f 一般文件
+++++++++ 添加文件

cL+++++++++

c 创建软链接档
L 软链接档
+++++++++ 添加软链接档

hf..t......

h 创建硬链接
f 一般文件
t 时间变更

可以同时测试运行(--dry-run-n),事先得知同步的情况
$rsync --dry-run -ai /path/to/d1 d2

created directory d2
cd+++++++++ ./
>f+++++++++ f1.txt

sent 236 bytes  received 63 bytes  598.00 bytes/sec
total size is 30  speedup is 0.10 (DRY RUN)
设置远程登录指令 (-e)
192.168.1.1 主机的 SSH 服务连接端口为 222,以选项 -e 设置远程登录指令
rsync -az -e 'ssh -p 222' ubuntu@192.168.1.1:/path/folder/ dest

远程登录的缺省指令为 ssh,参考 ssh 命令加入选项 -p,将指令变更为 ssh -p 222 以连接端口 222 登录 SSH。

同步扩展名及阶层
同步多个扩展名,原始目录下 (第一层) 的文件,子目录并不会同步
rsync \
--include="*.svg" \ (1)
--include="*.png" \
--include="*.jpg" \
--include="*.jpeg" \
--exclude='*' \ (2)
$srcPath $destPath
1 指定合乎的扩展名。
2 最后条件请按范例。
拷贝原始目录 (所有) 第 2 层的扩展名
rsync \
--include='/*/' \ (1)
--exclude='/*' \  (2)
--include="*.svg" \
--include="*.png" \
--include="*.jpg" \
--include="*.jpeg" \
--exclude='*' \
$srcPath $destPath
1 包含 1 ~ 2 层 ( 第 1 层是指原始目录下的文件,第 2 层为原始目录的子目录 )。
2 排除第 1 层 (先包含阶层再排除)。
包含阶层说明
rsync \
--include='*/' \ (1)

rsync \
--include='/*/' \ (2)
--include='/*/*/' \ (3)
--include='/*/*/*/' \ (4)
1 包含所有阶层
2 包含 1 ~ 2 层。
3 包含第 3 层 (必须先包含 1 ~2 层,才有作用)。
4 包含第 4 层 (必须先包含 1 ~2 层及第 3 层,才有作用)。
排除阶层
rsync \
--include='*/' \ (1)
--exclude='/*' \ (2)
--exclude='/*/*' \ (3)
--exclude='/*/*/*' \ (4)
1 先包含所有阶层再排除
2 排除第 1 层 (个别指定)
3 排除第 2 层 (个别指定,不需要先排除第 1 层)
4 排除第 3 层 (个别指定,不需要先排除第 1 或 2 层)

diff 列出文件差异

列出两个文件或目录的差异。

diff 语法
diff [参数] ... 文件或目录
diff 参数说明

-q, --brief

显示差异的文件,不显示差异内容,可用于比对两个目录的文件。

-r, --recursive

递归,含目录内的所有文件。

-c, -C[NUM], --context[=NUM]

以「上下文输出格式」显示源文件及新文件修改的情况,同时列出未变更的行数 (缺省为 3)。

-u, -U[NUM], --unified[=NUM]

以「统一格式」输出源文件修改情况,同时列出未变更的行数 (缺省为 3)。

-n, --rcs

以 RCS 格式显示 (以新文件的角度列出修改情况)。

-i, --ignore-case

忽略大小写。

-b, --ignore-space-change

不检查空白字符。

-w, --ignore-all-space

忽略所有空白字符,跟 -b 的差异在于直接忽略,如 ABCA B C 不视为差异。

-B, --ignore-blank-lines

忽略空行。

列出两个目录中文件内容不同的文件名 -q
diff -q folder1/ folder2/
Only in folder1: f1.txt
Only in folder2: f2.txt
Files folder1/f3.txt and folder2/f3.txt differ
比对子目录,加入递归 -r 选项
diff -qr folder1/ folder2/
在比对差异内容前,先创建两个测试档
cat > org.txt << EOF
line1-org
line2-same
del1
line3-org
del2
line4-same
del3
del4
line5-same
EOF

cat > new.txt << EOF
line1-mod
line2-same
line3-mod
line4-same
line5-same
line6-append
line7-append
EOF
比对差异 diff 第一个参数为源文件,第二个参数为新文件。
diff org.txt new.txt
1c1
< line1-org
---
> line1-mod
3,5c3
< del1
< line3-org
< del2
---
> line3-mod
7,8d4
< del3
< del4
9a6,7
> line6-append
> line7-append
1c1 (1)
< line1-org (2)
---
> line1-mod (2)
1 1c1 表示 (源文件的) 第 1 行换成了 (新文件的) 第 1 行。
2 < 源文件内容,> 新档内容。
3,5c3 (1)
< del1
< line3-org
< del2
---
> line3-mod
1 3,5c3 (源文件的) 3 至 5 行换成了 (新文件的) 第 3 行。 , 表示某行至某行,如 3,5c3,3 跟本例一样,当然开发者不会这样写;会合并相同行数。
7,8d4 (1)
< del3
< del4
1 7,8d4 (源文件的) 第 7 至 8 行删除成 (新文件的) 第 4 行。
9a6,7 (1)
> line6-append
> line7-append
1 9a6,7 (源文件的) 第 9 行添加至 (新文件的) 6 至 7 行。
diff -u (Unified context) 以「统一格式」输出源文件修改情况
diff -u org.txt new.txt
--- org.txt     2020-10-18 14:49:06.997670700 +0800
+++ new.txt     2020-10-18 14:49:07.935176100 +0800
@@ -1,9 +1,7 @@(1)
-line1-org
+line1-mod
 line2-same
-del1(2)
-line3-org
-del2
+line3-mod
 line4-same
-del3
-del4
 line5-same
+line6-append
+line7-append
1 提供给 patch 的数据,当未变更的行数设成 0 时 (-u0),可以发现还是存在 @@ 这些行,该行数据并非是「未变更」。
2 采用 -u 的表现只有 + -空白 没有仿真两可的修改情况,del1 (文件内容) 为删除。
如果只输出 + - (不输出其他) 采用自订输出
diff org.txt new.txt \
--old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format=''
diff -c (Copied context) 以「上下文输出格式」显示源文件及新文件修改的情况
diff -c org.txt new.txt
上方源文件及下方新文件的修改情况
*** 1,9 ****
! line1-org
  line2-same
! del1 (1)
! line3-org
! del2
  line4-same
- del3
- del4
  line5-same
--- 1,7 ----
! line1-mod
  line2-same
! line3-mod
  line4-same
  line5-same
+ line6-append
+ line7-append
1 字符符号说明: !(修改) +(添加) -(删除)、空白(未变更)。
del1 (文件内容) 是修改跟前面 3,5c3 虽然一致,但是并没有同时列示该组修改情况,并不知道 del1 实际上是删除, 采用 -c 需注意该问题,! 可能是删除 (注:选项 -u 则会标示成删除 -)。
diff -n (RCS format) 以新文件的角度列出修改情况
diff -n org.txt new.txt
d1 1 (1)
a1 1 (2)
line1-mod
d3 3 (3)
a5 1
line3-mod
d7 2
a9 2
line6-append
line7-append
1 采用 -n 是以新文件的角度列示, d1 1 在第 1 行删除 1 行。
2 a1 1 在第 1 行添加 1 行,不会有修改的情况,「修改」为先「删除」再「添加」。
3 del1 (文件内容) 为删除,以新文件的角度列示;不关心源文件,只列出 d3 3 在 3 行删除 3 行。

patch 补丁

patch 语法
patch [OPTION]... [ORIGFILE [PATCHFILE]]
patch 选项

-o FILE --output=FILE

输出补丁后的文件至 FILE

-i PATCHFILE --input=PATCHFILE

读取 PATCHFILE 补丁文件 (取代标准输入 stdin)。

-R --reverse

回复补丁 (已补丁的文件以 PATCHFILE 回复成补丁前的内容)。

difforg.txtnew.txt 产生补丁档 org.patch
diff -u org.txt new.txt > org.patch (1)
1 注意!diff 中的 -unified[NUM] 一并列出未变更的行数,不应设置 0,若补丁只有添加时,重复运行可能不会引发错误。另外 org.patch 即为前面 Unified context 内容,
org.txtorg.patch 补丁
patch org.txt org.patch
org.txtorg.patch 补丁,输出至另一个文件 orgmod.txt
patch org.txt -i org.patch -o orgmod.txt
比对 orgmod.txtnew.txt 应该相同 (即无输出).
diff -u orgmod.txt new.txt
以选项 -R,将 orgmod.txt 回复成 org.txt
patch orgmod.txt -R -i org.patch
比对 orgmod.txtorg.txt 应该相同
diff -u orgmod.txt org.txt

其他文件命令 (du df readlink)

du 查看目录占用容量

du -hd1 [目录]
-h 以可读性较高的方式来显示。
-d 最大阶层

du -hs [目录]
-s 合计该目录的总容量。

df 检查硬盘使用量

df -hl --total
-h 以可读性较高的方式来显示。
-l 仅显示本机的文件,不纳入挂载的文件。
--total 于最后一行加总
readlink -f 文件 ...
-f 符号链接范式 (跟随文件的符号链接)
$ readlink -f /usr/bin/which
/bin/which

$readlink -f ~ ~/..
/home/user
/home

输入与输出重新导向

输入与输出 (I/O) 重新导向是 Linux 系统中非常重要的功能,能够任意组合各种命令的输入和输出及串接任意的「命令管道」(command pipeline)。
在运行命令时,先创建好输出管道,再创建输入管道及串接管道。(大部份的命令在) 处理时并非将输入全部读取,而是读取一定的数据量,参与管道的命令「平行处理」输入与输出。

>>> 管道输出
ls > output.txt (1)
date >> output.txt (2)
1 将 ls「标准输出」至 output.txt 文件,这里为什么称为 「标准输出」,因为命令的输出事实上有「标准输出」及「错误输出」。
2 日期 输出附加在文件尾端 (如果文件不存在,则会创建新文件)。
< 管道输入
cat < input.txt (1)
cat < input.txt > output.txt (2)
1 cat 取得 (由管道输入) input.txt 数据后输出至主控台 (显示于屏幕上)。
2 cat 取得 input.txt 数据后,标准输出至 output.txt。
一般情况不会这样写,会采用由命令读取文件的方式 cat input.txt > output.txt
当输入文件跟输出文件相同时,如果以下列方式运行:
cat file.txt > file.txt

将得到一个空的 file.txt,其原因在于创建管道时,输出管道 > file.txt 会先运行将创建一个空的 file.txt

<< 管道输入终止字符串
cat > output.txt (1)

cat << EOF (2)
...
EOF
1 cat 需要标准输入管道,在没有重导的情况下,表示由主控台 (键盘) 输入,直到输入终止字符 Ctrl+d
2 由主控台输入,直到输入终止字符串 EOF。终止字符串,可任意命名。
line1='I am the first row'
line2='I am the second row'
cat > output.txt << EOF (1)
$line1
$line2
EOF (1)
1 终止字符串没有双 (单) 引号的情况下替换变量。
output.txt 的内容如下
I am the first row
I am the second row

接上例,把 EOF 改成 "EOF" 或者 'EOF'

cat > output.txt << "EOF" (1)
$line1
$line2
EOF
1 终止字符串有双 (单) 引号的情况下不会替换变量。
output.txt 的内容如下
$line1
$line2
另外可不采用双 (单) 引号的终止字符串,以反斜线 (\) 禁止转译变量。
cat > output.txt << EOF
\$line1
\$line2
EOF
| 串接管道

串接命令操作字符 | 将多个命令串接。串接前一个命令的正确输出管道;并不能处理错误的管道输出。命令处理后,再传递给下一个命令作为标准输入。串接管道的运行顺序是由左至右。

ls | cat -n (1)
ls | cat -n | grep -P '1\t' > output.txt (2)
1 ls 输出给 cat -n 加上行号后输出至主控台。
2 串接多个「命令管道」后标准输出至 output.txt,输出管道最先运行 (创建),串接管道的运行顺序是由左至右,先运行 lscat -n 再运行 grep -P '1\t'
输入及输出管道 (各别) 最多只能一个,不可能有多个,下列是将 ls 输出至 cat 文件。
ls > cat -n > output.txt

标准及错误输出

一般的 Linux 命令会有三个输入与输出的管道,分别为:
  • 标准输入 (stdin,代号 0):程序输入管道。
    注:一般命令都具有读取文件的功能,读取文件并不需要采用 < 来读取。

  • 标准正常输出 (stdout,代号 1):命令正常输出管道。

  • 标准错误输出 (stderr,代号 2):命令出错或状态消息 (可能) 以错误管道输出。

Linux 特殊文件:
  • /dev/null 是 Linux 空设备,写入这个文件的数据会被直接丢弃,如果从这个文件读取数据,则会像读取空文件一样。

  • /dev/stdout 标准正常输出,即为主控台。

  • /dev/stderr 标准错误输出,也是主控台。

ls 列出不存在的文件输出至 output.txt
$ls nonexistent > output.txt
ls: cannot access 'nonexistent': No such file or directory

上述的错误消息就是来自于 ls 的标准错误输出,output.txt 文件也会创建,不过内容是空的,因为命令没有任何标准正常输出。

输出管道可以采用操作符把正常管道 1> 输出至指定设备,或者是错误管道 2> 的输出设备。
注:标准输出管道 1> 可不需要指定操作符,1>> 相同。

ls 列出不存在的文件输出至 output.txt,错误输出至 error.txt
ls nonexistent 1> output.txt 2> error.txt
可先指定好管道,再传入参数。
ls 1> output.txt 2> error.txt nonexistent

运行后,主控台看不到任何消息。

错误消息是在 error.txt
ls: cannot access 'nonexistent': No such file or directory
正常及错误输出至同一设备,可采用 >&&>,将消息全部写入 all.txt
ls output.txt nonexistent &> all.txt
所有消息在 all.txt
ls: cannot access 'nonexistent': No such file or directory
output.txt
把正常及错误管道的消息输出至空设备 /dev/null,不会得到任何消息。
ls output.txt nonexistent &> /dev/null
合并管道

在运行命令时,可先设置合并管道。
2>&1,将管道 2 导入管道 1。
1>&2,将管道 1 导入管道 2。
要注意 linux 创建输出管道的顺序,是最右边先创建,「合并管道」要最先运行。

ls output.txt nonexistent 1> all.txt 2>&1

all.txt 的内容跟前面的「所有消息在 all.txt」一样。

合并管道顺序错误范例
ls output.txt nonexistent 2>&1 1> all.txt (1)
1 在主控台可看到错误消息,因为顺序不正确。合并管道 2>&1 要最先运行才有作用 (创建输出管道的顺序,是最右边先创建)。
输出重导至标准输出发生权限错误
$echo 123 > /dev/stdout
bash: /dev/stdout: Permission denied

$echo 123 > /dev/stderr
bash: /dev/stderr: Permission denied
当登录为 user1 以 su 切换至另一个 user2 用户,是造成本问题的原因
su user2

dev/stdout 是一个符号链接到 /proc/self/fd/1,再以符号链接至伪终端,例如:dev/pts/1。伪终端权限是在登录时授予,当以 su user2 切换至不同的帐户时,伪终端的拥有权并不会更改,user2 没有写入权限。
注:su root 不会错误,超级用户不受权限影响。

user2 的伪终端权限
$ls /dev/stdout /proc/self/fd/1 /dev/pts/1 -lU
lrwxrwxrwx 1 root   root     15 2023-03-10 04:25 /dev/stdout -> /proc/self/fd/1
lrwx------ 1 user2 user2     64 2023-03-15 11:58 /proc/self/fd/1 -> /dev/pts/1
crw--w---- 1 user1 tty   136, 1 2023-03-15 11:58 /dev/pts/1

文件内容查阅

cat   显示文件所有内容。
head  显示文件开头的内容。
tail  显示文件尾端的内容。
more  一页一页向后显示内容 (可向上翻页仅限文件,管线无作用)。
less  与 more 类似,但比 more 更容易操作,可前后翻页。

上述的命令与本文编辑器 (例如 nano 或 vim) 相比,启动时不需要读取整个文件,加载时间会大大缩短,可用于打开大文件。

cat 显示文件所有内容
cat [参数] [文件]
-n 打印出行号
-E 将行尾的断行字符以 $ 显示
-T 将字符 tab 以 ^I 显示
head 显示文件开头的内容
head -n20 /var/log/auth.log
-n 20, 显示 20 行,缺省为 10 行。
tail 显示尾端内容
tail -n20 -f /var/log/auth.log
-n 20, 显示 20 行,缺省为 10 行。
-f 持续监控文件内容,当有新数据时即时显示。离开监控模式需按下 Ctrl+c 中断监控。

more 查看命令

more /var/log/auth.log
以下是 more 一些查看时常用的命令:
Shortcut Purpose

q

离开 more

h

显示说明

Enter

向下一行

空白键f

向下翻页

bCtrl+b

向上翻页 (仅限文件,管线无作用)

/ 字符串

向前搜索「字符串」

n

重复上一个搜索 (向前),跟 / 有关。 没有向后的功能。

less 查看命令

less 一次显示一页文件或命令输出 (pipe) 的内容,跟 more 相似但具有更好的功能;如可翻页内容。

less /var/log/auth.log
用管线将说明发送给 less
rsync --help | less
以下是一些查看时常用的命令:
Shortcut Purpose

q

离开 less

h

显示说明,离开说明则按下q

PageDown空白键f

向下翻页

PageUpb

向上翻页

g

至文件开头

Shift+G

至文件尾端

/ 字符串

向前搜索「字符串」

? 字符串

向后搜索「字符串」

n

重复上一个搜索 (向前),跟 / ? 有关。

Shift+N

反向重复先前的搜索 (向后),跟 / ? 有关。

- i

切换搜索是否区分大小写,缺省为区分大小写。

- N

切换是否显示行号

grep 找出符合模式的「行」

grep 语法
grep [选项]... PATTERN(模式) [文件]...
grep 选项

Pattern selection and interpretation:

-e, --regexp=PATTERN

以 PATTERN 进行匹配

-E, --extended-regexp

PATTERN 为延伸正规表示法 (ERE)

-w, --word-regexp

PATTERN 匹配单词,如匹配 word,words 则不匹配。

-i, --ignore-case

不区分大小写

Miscellaneous:

-v, --invert-match

反向匹配,找出不合乎符合模式的「行」。

Output control:

-r, --recursive

递归,含目录内的所有文件

-n, --line-number

打印行号

-T, --initial-tab

将字符 tab 以 ^I 显示

-l, --files-with-matches

仅列出文件内容符合模式的文件名

--include=FILE_PATTERN

仅搜索 GLOB 匹配 FILE_PATTERN 的文件

Context control:

-B, --before-context=NUM

列出匹配前 NUM 行数

-A, --after-context=NUM

列出匹配后 NUM 行数

grep 匹配多个模式
grep 'Pattern1\|Pattern2' file...
grep -E 'Pattern1|Pattern2' file...
grep 找出目前目录内符合模式的文件名 (不列示内容)
grep -rl PATTERN
找出 /etc 目录内的特定文本 (hosts):
grep -rw hosts /etc
grep 如果按语法顺序,可不需要 -e 选项,但习惯在把路径写在前面,则加入 -e 选项,并把表示法加上单引号比较清楚。
grep /etc -e 'hosts' -rw
找出 /etc 目录内特定扩展名 (GLOB 匹配) 中的单词 (w) 文本 (hosts):
grep /etc -e 'hosts' -rw --include=*.allow --include=*.deny
grep /etc -e 'hosts' -rw --include=*.{allow,deny}

cut 截取部份字符或字段

cut 命令格式
cut 选项... [文件]...
cut 选项

-f, --fields=LIST

以定界字符区分出字段,截取字段。

-c, --characters=LIST

截取字符。

-b, --bytes=LIST

截取字节。

-d, --delimiter=DELIM

定界字符,缺省为制表字符 (Tab 键),只允许一个字符。

--complement

补集参数,将指定的部份删除,留下剩余的部份。

--output-delimiter=STRING

将定界字符取代成 STRING

-s, --only-delimited

只打印具有定界字符的行。

-f-c-bLIST 的参数可以是整数、以逗号分隔的多个整数,或者是范围、以逗号分隔的多个范围。

范围可以是以下之一:

n

n 个字段、字符或字节。

n-

n 个字段、字符或字节到 (该行的) 结尾。

n-m

由第 n 至第 m 个字段、字符或字节。

-m

由第一个至第 m 个字段、字符或字节。

选项 -c,截取字符

如截取前面 6 个字符为 1-6,截取第 7 个字符至结束如 7-

数据如下
$grep ubuntu /etc/passwd
ubuntu:x:1000:1000::/home/ubuntu:/bin/bash
截取字符 -c 范例
grep ubuntu /etc/passwd | cut -c 1-6 (1)
grep ubuntu /etc/passwd | cut -c -6 (1)
grep ubuntu /etc/passwd | cut -c 7- (2)
grep ubuntu /etc/passwd | cut -c 1-6 --complement (3)
1 截取前面 6 个字符
ubuntu
2 截取第 7 个字符至结束
:x:1000:1000::/home/ubuntu:/bin/bash
3 去掉前面 6 个字符,留下剩余的部份。
:x:1000:1000::/home/ubuntu:/bin/bash
选项 -d 指定定界字符
以选项 -d 指定定界字符 :,将数据标示出字段如下:
ubuntu:x:1000:1000::/home/ubuntu:/bin/bash
1     :2:3   :4   ::6           :7
定界字符 -d:,截取字段 -f
grep ubuntu /etc/passwd | cut -d : -f 1,6  (1)
grep ubuntu /etc/passwd | cut -d : -f 1,6 --output-delimiter=' ' (2)
1 截取字段 1、6。
ubuntu:/home/ubuntu
2 截取字段 1、6,将定界字符取代成空白。
ubuntu /home/ubuntu
只打印具有定界字符 (-s) 的行
ls /bin -l | cut -d '>' -s -f 1,2

awk 找出符合字段的「行」

本文已移至 awk

sed

本文已移至 sed