利用AWK命令编辑电子书的文件名

TCP/IP电子书整理指南
本文介绍了一种方法,用于将《TCP/IP详解》电子书的各章节PDF文件名转换为更具描述性的名称,便于管理和查找。通过使用grep和awk等命令处理目录文件,实现了文件名的有效转换。

最近在学习TCP/IP,从网上下载了《TCP/IP详解》的电子书。电子书是分章节的若干个PDF文件,每章一个文件,文件名是如下面的文件1所示。

文件1:name.txt

01.pdf
02.pdf
03.pdf
04.pdf
05.pdf
……
……

从这些文件名中看不出每个文件的内容是什么。还好下载文件里里面有个目录文件,含有本书的详细目录,如下所示:
……
……
第3章 IP:网际协议
3.1 引言
3.2 IP首部
3.3 IP路由选择
第4章 ARP:地址解析协议
4.1 引言
4.2 一个例子
4.3 ARP高速缓存
……
……

我想通过这个目录文件把文件名转换成如下所示的结构:

想转换成的文件2:result.txt
01概述.pdf
02链路层.pdf
03IP网际协议.pdf
04ARP地址解析协议.pdf
05RARP逆地址解析协议.pdf

为了达成这个目的,第一步是把目录文件精简成如下所示的chapter.txt
可以利用命令grep -oP ‘(?<=(章)) .*' 目录.txt > chapter.txt

-o是指只显示匹配的部分。
-P是利用PERL的正则表达式形式。
(?<=)是后向匹配符号。

生成的文件如下所示:

文件3:chapter.txt

概述
链路层
IP网际协议
ARP地址解析协议
RARP逆地址解析协议
……
……

再用awk命令处理这两个文件,以形成最后的结果(最重要的一个步骤):

命令如下:
awk 'BEGIN{OFS=FS="."} NR==FNR{a[NR]=$0}NR>FNR{$1=$1 a[FNR];print}' chapter.txt name.txt > result.txt

首先设定域分隔符OFS=FS="."
NR:当前记录数。
FNR:同NR,但相对于当前文件。
首先单独扫描第一个文件chapter.txt,利用条件NR==FNR,是if条件语句的简写形式。也可写成{if(NR==$0) a[NR]=$0}.
之后单独扫描第二个文件name.txt,利用条件NR>FNR。
字符串连接直接用空格即可,即$1=$1 a[FNR]。如果用加号的话,系统会把字符串转换成数值后再进行数值的加减。
生成的文件是unix格式,要想在windows下正常显示,可以使用命令unix2dos result.txt.

最后利用TotalCommander软件的文件批量重命名中的“从文本文件中导入文件名”功能,将result.txt文件加载成电子书目录下的文件名,至此,大功告成。

<think>我们使用awk来过滤文件名,但注意:ls命令的输出可能包含除文件名外的其他信息(如使用-l选项时)。为了安全地过滤文件名,最好确保只处理文件名。 通常,简单情况下,直接使用`ls | awk`是可行的,因为默认ls输出的就是文件名(一行一个)。但如果目录中有特殊字符或空格,可能需要更谨慎的处理。 用户要求过滤“前缀文件名”,假设是指文件名以某个字符串开头。这我们可以使用awk的模式匹配来实现。 例如:列出所有以"prefix"开头的文件,可以: ls | awk '/^prefix/' 解释: - `^` 在正则中表示字符串的开始。 - 因此,`/^prefix/` 只会匹配以"prefix"开头的行(即文件名)。 注意:如果文件名包含换行符等,这种方法可能不适用,但一般情况下可行。 如果需要忽略大小写,可以这样: ls | awk 'tolower($0) ~ /^prefix/' 但更简单的方式是使用awk的IGNORECASE变量(注意:不是所有awk版本都支持,GNU awk支持): ls | awk 'BEGIN{IGNORECASE=1} /^prefix/' 如果不支持IGNORECASE,则可以转换为小写或大写再比较。 另外,如果只想打印匹配的文件名,模式匹配后默认就会打印,所以不需要显式写print。 因此,针对过滤前缀文件名,基本命令是:`ls | awk '/^你的前缀/'` 如果前缀包含正则特殊字符(如.、*等),需要进行转义,或者使用index函数进行字符串匹配(非正则): ls | awk 'index($0, "your_prefix")==1' 因为index返回子串的位置,如果等于1,说明在开头。 所以,根据前缀是正则表达式还是固定字符串,可以选择不同的方法。 下面给出两种方式的示例: 1. 正则表达式匹配(如前缀为"abc"): `ls | awk '/^abc/'` 2. 固定字符串匹配(如前缀为"abc"): `ls | awk 'substr($0,1,3)=="abc"'` 或者 `ls | awk 'index($0,"abc")==1'` 注意:固定字符串匹配中,第二种方法使用index更灵活,不需要知道长度,但需要确保字符串在开头。 根据用户要求,我们只回答如何用awk过滤前缀文件名,因此总结: - 使用正则:`ls | awk '/^前缀/'` - 使用固定字符串:`ls | awk 'index($0, "前缀")==1'` 但是请注意,如果目录中文件很多,使用管道可能不是最高效的,而且ls的输出可能被解析多次(如果文件名包含特殊字符可能会有问题)。更推荐使用`find`或直接使用shell通配符(如`ls prefix*`),但既然要求用awk,我们就用awk。 最后,按照要求,在回答后提出3-5个相关问题。 </think>要将 `ls` 输出中带有指定前缀的文件名用 `awk` 过滤出来,可以使用以下命令: ```bash ls | awk '$0 ~ /^prefix/ {print}' ``` ### 解释: 1. `ls`:列出当前目录的文件名(默认每行一个文件名) 2. `awk '$0 ~ /^prefix/'`: - `$0` 表示整行内容 - `~` 是匹配操作符 - `/^prefix/` 是正则表达式,`^` 匹配行首,`prefix` 是您需要的前缀字符串 - 默认动作 `{print}` 可省略(匹配时自动打印整行) ### 示例: - 过滤以 `log_` 开头的文件名: ```bash ls | awk '/^log_/' ``` - 过滤以 `backup_` 开头的文件名: ```bash ls | awk '/^backup_/' ``` ### 注意事项: - 文件名含空格也能正确处理(每行一个文件名) - 若需忽略大小写,添加 `IGNORECASE=1`: ```bash ls | awk 'BEGIN{IGNORECASE=1} /^prefix/' ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值