shell 学习笔记 文件操作 下

摘自 Linux Shell 脚本攻略 第三章 以文件之名

枚举文件类型统计信息

用下面的命令打印文件类型信息

$ file a.txt 
a.txt: ASCII text

打印不包括文件名在内的文件类型信息

$ file -b a.txt 
ASCII text

生成文件统计信息的脚本

$ cat filestat.sh 
# !/bin/bash
# 文件名: filestat.sh
if [ $# -ne 1 ];
then
  echo "Usage is $0 basepath";
  exit 
fi
path=$1
declare -A statarray;
for line in `ls -l $path |grep ^-|awk '{print $NF}'`;do   # 遍历目标文件夹下的所有文件
  ftype=`file -b "$line" | cut -d, -f1` # file -b 列出辨识结果时,不显示文件名称
  let statarray["$ftype"]++; # 存入 关联数组
done
echo ============ File types and counts =============
for ftype in "${!statarray[@]}";do # 遍历关联数组
  echo $ftype :  ${statarray["$ftype"]} 
done
$ ./filestat.sh /home/amlogic/coco/a/
============ File types and counts =============
empty : 2
ASCII text : 2
UTF-8 Unicode text : 1

使用环回文件

Linux文件系统通常存在于磁盘或记忆棒(memory stick)这种设备上。文件其实也可以作为 文件系统挂载。这种存在于文件中的文件系统(filesystem-in-a-file)可用于测试、文件系统定制或者是作为机密信息的加密盘。

用mkfs命令将1GB的文件格式化成ext4文件系统

# 使用dd命令创建一个1GB大小的文件
$ dd if=/dev/zero of=loobackfile.img bs=1G count=1
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.610861 s, 1.8 GB/s

$ mkfs.ext4 loopbackfile.img
mke2fs 1.45.6 (20-Mar-2020)
Discarding device blocks: done                            
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: bbcf3e24-c69d-48a4-a957-09a794d0dbef
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

使用file命令检查文件系统

$ file loopbackfile.img 
loopbackfile.img: Linux rev 1.0 ext4 filesystem data, UUID=bbcf3e24-c69d-48a4-a957-09a794d0dbef (extents) (64bit) (large files) (huge files)

使用mkdir创建挂载点并挂载环回文件

$ sudo mkdir /mnt/loopback
$ sudo mount -o loop loopbackfile.img /mnt/loopback

也可以使用以下命令来指定具体的环回设备

# losetup /dev/loop1 loopbackfile.img
# mount /dev/loop1 /mnt/loopback

使用下面的方法进行卸载(umount)

# umount mount_point
$ sudo umount /mnt/loopback

也可以用设备文件的路径作为umount命令的参数

# umount /dev/loop1

注意,因为mount和umount都是特权命令,所以必须以root用户的身份来 执行

在环回镜像中创建分区

假设我们需要创建一个环回文件,然后对其分区并挂载其中某个分区。在这种情况下,没法使用mount - o loop。我们必须手动建立设备并挂载分区
使用下面的方法对文件(内容全部填充为0)进行分区

# losetup /dev/loop1 loopback.img
# fdisk /dev/loop1

在loopback.img中创建分区并挂载第一个分区

# losetup -o 32256 /dev/loop2 loopback.img

/dev/loop2表示第一个分区,-o用来指定偏移量,在DOS分区方案1中,这个偏移量是32256。 第一个分区在硬盘上起始于32 256字节处
我们也可以指定所需的偏移量来挂载第二个分区。完成挂载之后,就可以像在物理设备上一 样执行所有日常操作了

快速挂载带有分区的环回磁盘镜像

如果我们希望挂载环回磁盘镜像中的分区,可以通过参数的形式将分区偏移量传递给 losetup命令。不过,有一个更快的方法可以挂载镜像中的所有分区:kpartx。该命令默认并 没有安装在系统中,你得使用软件包管理器来安装

# kpartx -v -a diskimage.img
add map loop0p1 (252:0): 0 114688 linear /dev/loop0 8192
add map loop0p2 (252:1): 0 15628288 linear /dev/loop0 122880

这条命令在磁盘镜像的分区与/dev/mapper中的设备之间建立了映射,随后便可以挂载这些设备 了。下列命令可以用来挂载第一个分区

# mount /dev/mapper/loop0p1 /mnt/disk1

当你完成设备上的操作后(并使用umount卸载所有挂载过的分区),使用下列命令移除映射 关系

# kpartx -d diskimage.img
loop deleted : /dev/loop0

将ISO文件作为环回文件挂载

ISO文件是光学存储介质的归档。我们可以采用挂载环回文件的方法,像挂载物理光盘一样
挂载ISO文件。
我们甚至可以用一个非空目录作为挂载路径。在设备被卸载之前,这个挂载路径中包含的都
是来自该设备的数据,而非目录中的原始内容

# mkdir /mnt/iso
# mount -o loop linux.iso /mnt/iso

现在就可以对/mnt/iso中的文件进行操作了。ISO是一个只读文件系统

使用sync立刻应用更改

对挂载设备作出的更改并不会被立即写入物理设备。只有当内部缓冲区被写满之后才会回写
设备。我们可以用sync命令强制立刻写入更改

$ sync

生成ISO及混合型ISO文件

ISO镜像是一种存档格式,它存储了如CD-ROM、DVD-ROM等光盘的精准镜像。ISO文件通常用于存储待刻录的数据

我们需要区分可引导光盘与不可引导光盘。可引导光盘自身具备引导能力,也可以运行操作
系统或其他软件。系统安装盘和Live系统(如Knoppix和Puppy)都属于可引导光盘。

不可引导光盘则做不到这些。升级盘和源代码DVD都属于不可引导光盘

从/dev/cdrom创建一个ISO镜像

# cat /dev/cdrom > image.iso
# dd if=/dev/cdrom of=image.iso # 推荐使用

mkisofs命令可以创建ISO镜像文件。该命令生成的输出文件能够被cdrecord这类实用工具 刻录到CD-ROM或DVD-ROM。我们需要将所有文件放入同一个目录中,然后用mkisofs命令将 整个目录中的内容写入ISO文件

$ mkisofs -V "Label" -o image.iso source_dir/

其中选项-o指定了ISO文件的路径。source_dir是作为ISO文件内容来源的目录路径,选项-V 指定了ISO文件的卷标

能够启动闪存或硬盘的混合型ISO

通常无法通过将可引导的ISO文件写入USB存储设备来创建可引导的U盘。但是有一种被称
为“混合ISO”的特殊ISO文件可以实现这一点。

我们可以用isohybrid命令把标准ISO文件转换成混合ISO。isohybrid是一个比较新的实 用工具,尚未包含在大多数的Linux发行版中。你可以从http://www.syslinux.org下载syslinux软件 包,也可以使用yum或apt-get获取syslinux-utils。

下面的命令能够制作出可引导的ISO文件

# isohybrid image.iso

这个混合型ISO文件可用于写入USB存储设备。
将该ISO写入USB存储设备:

# dd if=image.iso of=/dev/sdb1

你可以用相应的设备代替/dev/sdb1,或者使用cat命令:

# cat image.iso >> /dev/sdb1

用命令行刻录ISO

cdrecord命令可以将ISO文件刻入CD-ROM或DVD-ROM。
使用下列命令刻录CD-ROM

# cdrecord -v dev=/dev/cdrom image.iso

还有一些其他选项

  • 使用-speed选项指定刻录速度
# cdrecord -v dev=/dev/cdrom image.iso -speed 8 # 参数8表明其刻录速度未8x
  • 刻录CD-ROM时也可以采用多区段(multi-session)方式,这样就能在一张光盘上分多次 刻录数据。多区段刻录需要使用-multi选项
# cdrecord -v dev=/dev/cdrom image.iso -multi

玩转CD-ROM托盘

  • 弹出光驱托盘
$ eject
  • 合上光驱托盘
$ eject -t

查找并修补文件差异

version1.txt

$ cat version1.txt 
this is the original text
line2
line3
line4
happy hacking !

version2.txt

$ cat version2.txt 
this is the original text
line2
line4
happy hacking !
GNU is not UNIX

非一体化(nonunified)形式的diff输出

**$ diff version1.txt version2.txt
3d2
< line3
5a5
> GNU is not UNIX**

一体化形式的diff输出如下

$ diff -u version1.txt version2.txt
--- version1.txt        2021-11-20 11:53:02.406463710 +0800
+++ version2.txt        2021-11-20 11:53:20.462204281 +0800
@@ -1,5 +1,5 @@
 this is the original text
 line2
-line3
 line4
 happy hacking !
+GNU is not UNIX

选项-u用于生成一体化输出。因为一体化输出的可读性更好,更易于看出两个文件之间 的差异,所以人们往往更喜欢这种输出形式
在一体化diff输出中,以+起始的是新加入的行,以-起始的是被删除的行

修补文件可以通过将diff的输出重定向到一个文件来生成

$ diff -u version1.txt version2.txt > version.patch

现在就可以用patch命令将变更应用于其中任意一个文件。当应用于version1.txt时,就可 以得到version2.txt;而当应用于version2.txt时,就得到了version1.txt

用下列命令来进行修补

$ patch -p1 version1.txt < version.patch -R # -R 不提示用户选择y/n 直接执行
patching file version1.txt

生成目录的差异信息

$ diff -Naur directory1 directory2
  • -N:将缺失的文件视为空文件。
  • -a:将所有文件视为文本文件。
  • -u:生成一体化输出。
  • -r:递归遍历目录下的所有文件。

使用head与tail打印文件的前10行和后10行

打印前10行

o$ head coco.sh
#!/bin/bash


/USSR/bin/expect <<-OF &>/Devi/null
spawn ssh amlogic@10.18.19.233
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "Linux2021\r" }
}
expect of

从stdin读取数据:

$ cat coco.sh | head
#!/bin/bash


/USSR/bin/expect <<-OF &>/Devi/null
spawn ssh amlogic@10.18.19.233
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "Linux2021\r" }
}
expect of

指定打印前几行

$ head -n 4 coco.sh
#!/bin/bash


/USSR/bin/expect <<-OF &>/Devi/null

打印除了最后M行之外所有的行

$ head -n -5 coco.sh
#!/bin/bash


/USSR/bin/expect <<-OF &>/Devi/null
spawn ssh amlogic@10.18.19.233
expect {
"yes/no" { send "yes\r";exp_continue }

注意,这里的-M表示的是负数,并非选项

$ seq 11 | head -n -5
1
2
3
4
5
6

打印文件的最后10行

$ tail coco.sh

/USSR/bin/expect <<-OF &>/Devi/null
spawn ssh amlogic@10.18.19.233
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "Linux2021\r" }
}
expect of
OF

从stdin中读取输入

$ cat coco.sh | tail

/USSR/bin/expect <<-OF &>/Devi/null
spawn ssh amlogic@10.18.19.233
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "Linux2021\r" }
}
expect of
OF

打印最后5行

$ tail -n 5 coco.sh
"password:" { send "Linux2021\r" }
}
expect of
OF

打印除了前M行之外所有的行

$ tail -n +(M+1)
$ tail -n +6 coco.sh
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "Linux2021\r" }
}
expect of
OF

例如,打印除前5行之外的所有行,M+1=6,因此使用下列命令

$ seq 10 |tail -n +6
6
7
8
9
10

使用tail 监视文件

$ tail -f growing_file

实例

# 建立logcat 管道
% adb logcat > coco.log &
[1] 1873
# 监控logcat 文件
% tail -f coco.log
11-19 22:20:59.437   388   544 I DTVKIT_LOG: TunerTask:2973 0: Waiting for tune request....
11-19 22:21:00.437   388   544 I DTVKIT_LOG: TunerTask:2973 0: Waiting for tune request....
11-19 22:21:00.828   388   546 I DTVKIT_LOG: FdWriteTask:148 no file is read
11-19 22:21:01.437   388   544 I DTVKIT_LOG: TunerTask:2973 0: Waiting for tune request....
...

# 停止logcat 
% kill -9 1873

11-19 22:21:15.831   388   546 I DTVKIT_LOG: FdWriteTask:148 no file is read
[1]  + killed     adb logcat > coco.log
# 监控 停止输出
# 但是 tail 命令并未退出

# 使用 --pid $PID 选项可以在该进程停止运行后 退出tail 交互

只列出目录的各种方法

使用ls -d

$ ls -d */
3d/  4k/  a/  for_fun/  picture/

使用grep结合ls -F

$ ls -F | grep "/$"
3d/
4k/
a/
for_fun/
picture/

使用grep结合ls -l

$ ls -l | grep "^d"
drwxrwxr-x 2 amlogic amlogic      4096 11月  3 11:21 3d
drwxrwxr-x 2 amlogic amlogic      4096 11月 17 17:05 4k
drwxrwxr-x 2 amlogic amlogic      4096 11月 19 17:29 a
drwxrwxr-x 3 amlogic amlogic      4096 11月 17 20:52 for_fun
drwxrwxr-x 8 amlogic amlogic      4096 11月 11 16:57 picture

使用find

$ find . -maxdepth 1 -type d -print
.
./for_fun
./a
./picture
./3d
./4k

在命令行中使用pushd和popd实现快速定位

pushd和popd可以用于在多个目录之间切换而无需重新输入目录路径。这两个命令会创建一
个路径栈,它是一个保存了已访问目录的LIFO列表(LastInFirstOut,后进先出)

压入并切换路径

:~/coco$ pushd /var/www
/var/www ~/coco
:/var/www$ 

再压入下一个目录路径

:/var/www$ pushd /usr/src
/usr/src /var/www ~/coco
:/usr/src$

查看栈的内容

$ dirs
/usr/src /var/www ~/coco

当你想切换到栈中任意一个路径时,将每条路径从0编号到n,然后使用你希望切换到的 路径编号

:/usr/src$ pushd +2
~/coco /usr/src /var/www
:~/coco$

根据dirs返回值 计算下标

删除最近压入的路径并切换到下一个目录

:~/coco$ popd
/usr/src /var/www
:/usr/src$

假设现在栈包含/usr/src /var/www ~ /usr/share /etc,当前目录是 /usr/src,popd会将栈更
改为/var/www ~ /usr/share /etc,然后把当前目录切换至/var/www

统计文件的行数、单词数和字符数

统计行数

$ wc -l coco.sh 
12 coco.sh

如果需要将stdin作为输入,使用下列命令

$ cat coco.sh |wc -l
12

统计单词数

$ wc -w coco.sh 
23 coco.sh
$ cat coco.sh |wc -w
23

统计字符数

$ wc -c coco.sh 
180 coco.sh
$ cat coco.sh |wc -c
180

$ echo coco is handsome |wc -c
17

不使用任何选项时,wc会打印出行、单词和字符的数量

$ wc coco.sh 
 12  23 180 coco.sh

这些分别是文件的行数、单词数和字符数

使用-L选项打印出文件中最长一行的长度

$ wc coco.sh -L
38 coco.sh

打印目录树

tree命令能够以图形化的树状结构打印文件和目录。Linux发行版中通常不包含这个命令。
你需要用包管理器自行安装

$ tree 3d/
3d/
└── [CNUHD] LG 4K3D .mp4

0 directories, 1 file
  • -P选项可以只显示出匹配指定模式的文件
$ tree . -P '*.sh'
.
├── 3d
├── 4k
├── a
│   └── remove_duplicates.sh
├── build1.sh
├── cecho.sh
├── coco.sh
├── debug.sh
├── filestat.sh
├── for_fun
├── picture
│   ├── bmp
│   ├── gif
│   ├── jpg
│   ├── pic
│   ├── png
│   └── tiff
├── remove_duplicates.sh
└── shift.sh

11 directories, 8 files
  • -I选项可以只显示出不匹配指定模式的文件
tree path -I PATTERN
  • -h选项可以同时打印出文件和目录的大小
$ tree 3d/ -h
3d/
└── [415M]  [CNUHD] LG 4K3D .mp4

0 directories, 1 file

生成HTML形式的目录树

% tree . -H http://localhost -o out.html

tree 生成html文件

处理视频与图像文件

Linux和Unix都拥有很多能够处理图像和视频文件的应用程序和工具。大多数的Linux发行版 中都包含了ImageMagick套件,其中的convert程序可用于处理图像。像kdenlive和openshot这种全 功能的视频编辑程序都是构建在命令行程序ffmpeg和mencoder之上的

下面的命令能够将mp4视频文件(FILE.mp4)中的音频部分提取成mp3文件(OUTPUTFILE.
mp3)

ffmpeg -i FILE.mp4 -acodec libmp3lame OUTPUTFILE.mp3

使用一组静态图像制作视频

$ cat stills2mpg.sh
echo $* | tr ' ' '\n' >files.txt
mencoder mf://@files.txt -mf fps=24 -ovc lavc -lavcopts vcodec=msmpeg4v2 -noskip -o movie.mpg

./stills2mpg.sh *.jpg

使用静态照片生成平移视频

$ cat makePan.sh
# 调用方法:
# sh makePan.sh OriginalImage.jpg prefix width height xoffset yoffset # 清除旧数据
rm -f tmpFiles
# 创建200张静态图片,每次移动xoffset和yoffset个像素
for o in `seq 1 200`
  do 7 x=$[ $o+$5 ]
  convert -extract $3x$4+$x+$6 $1 $2_$x.jpg
  echo $2_$x.jpg >> tmpFiles
done
#将图片拼合成mpg视频文件
mencoder mf://@tmpFiles -mf fps=30 -ovc lavc -lavcopts vcodec=msmpeg4v2 -noskip -o $2.mpg

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Shell命令时,以下是一些重要的注意事项和学习建议: 1. 基本语法:Shell命令通常由命令名称和参数组成。命令名称是要执行的操作,而参数则提供了命令所需的信息。了解Shell命令的基本语法是学习的第一步。 2. 命令帮助:大多数Shell都提供了内置的命令帮助功能。通过使用命令后跟`--help`或`-h`选项,或者使用`man`命令(例如`man ls`)来获取有关特定命令的详细信息。 3. 常用命令:有一些常见的Shell命令对于日常使用非常有用。这些包括`cd`(更改目录)、`ls`(列出目录内容)、`mkdir`(创建目录)、`rm`(删除文件或目录)等。逐步学习和掌握这些命令是很重要的。 4. 管道和重定向:Shell命令非常强大,可以通过管道和重定向符号将多个命令组合在一起。了解如何使用管道(`|`)将一个命令的输出作为另一个命令的输入,并使用重定向符号(`>`、`>>`、`<`)来控制输入和输出。 5. 脚本编写:Shell脚本是一种将多个命令组合在一起以自动化任务的方法。学习如何编写简单的Shell脚本可以提高工作效率。 6. 实践和练习:最重要的是进行实践和练习。尝试使用不同的Shell命令来完成各种任务,并在实际场景中应用所学知识。 记住,Shell命令的学习是一个逐步的过程。开始时可能会有些困惑,但随着实践和经验的积累,你会变得越来越熟练。希望这些提示对你有帮助!如有任何具体问题,随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值