很高兴和你相遇
这里正在记录我的所思所学
邮箱 [email protected]
首页 标签 归档 播客 主页 简历

三个 Linux 文件高频小操作

去除文件名后缀

在 Linux 中跑各种任务或者循环命令的时候,有一个高频的需求是截取一部分文件名。例如有文件 XXX_aaa.bb 和 YYY_aaa.bb ,很可能我们需要提取出 XXX 和 YYY 来给后续的文件进行命名。

实现这个需求的方法有不少。

利用变量中的 % 号。在 Linux 中使用百分号将变量的内容从变量的尾部删除。 一个%号可以从尾部最近位置进行匹配删除,两个%%从尾部最远位置匹配删除。同时支持使用通配符。例如id=XXX_aaa.bb 可以使用${id%%_*}

第二种方式是使用 cut cut -d ‘_’ -f 1。使用 _ 作为分隔符,输出第一列,也是可以得到 XXX

第三种是使用 awk,和 cut 类似也是指定分隔符输出第一列 ls *.bb| awk -F "_" '{print $1 }'

为了让脚本使用率更高一些,我通常会使用绝对路径来指定文件位置。为了更快的获取文件名,会使用命令 basename。basename 本身就有一个非常好用的功能,可以剔除指定的文件名结尾部分。如下所示,我觉得这个应该是最优雅的方式。

basename /a/b/c/XXXX_aaa.bb _aaa.bb
XXXX

批量重命名

场景如下,现在有好几百个文件需要重命名。类似于 A1.txt A1.md A1.pdf B2.txt B2.md B2.pdf ...
其中 A1 要全部替换为 C3 ,B2 要全部替换为 D4 变为,即 C3.txt C3.md C3.pdf D4.txt ...
已经有一个两列的文件是对应信息。

A1 C3
B2 D4

昨天在知识星球抛出这个问题之后有几个小伙伴给出了自己的建议,其中给我最大冲击的是一个小伙伴提出的 Excel 批量法,思路是用 Excel 对字符段组合出新的命令。

这个需求或许可以拆解为两个问题,一个是重命名,一个是批量。

重命名的方法 mv 或者 rename 都可以,批量很容易想到 for 循环,因为对应的一对变量已经在文件的一行了,所以只要把它们分别保存为两个变量就好了。这个需求更好的完成是方式是配合 while 和 read 来完成循环。
read 可以从标准输入或者管道以及文件描述符读取内容,而且非常方便的可以直接定义多个变量。

因此可以写为:

while read old new
do
echo $old $new;
rename "s/${old}/${new}/" ${old}*
done<changename.txt

如果把这个小小的命令变成一个 rename.sh 脚本,可以写成。

#!/bin/bash
FILE=$1
while read old new
do
echo $old $new;
rename "s/${old}/${new}/" ${old}*
done < $FILE

多说一句,关于理解 read 的用法,有一个小的测试题。

echo '1 2 3 4 5 6' | while read a b c
do
  echo $c $b $a
done

上面这个命令,请问输出的结果是什么?是 3 2 1 6 5 4 么?如果不是又会是什么呢?如果能直接说出 3 4 5 6 2 1 这个结果,应该就是理解了。

同文件名文件拷贝

这个需求也比较常见,在 Linux 中,不能的目录下都有可能存在相同的文件名,例如有些生信分析软件跑多套数据,通常只会在目录层面进行区分,而不会在文件名层面进行区分。可能的目录结果如下:

a: xx.txt yy.json zz.bam
b: xx.txt yy.json zz.bam

为了方便处理,我们通常习惯把同一个类型的文件放在一起,但是如果直接拷贝源文件,会因为文件名重复的问题带来灾难。这时就有了一个重命名再拷贝的问题。

重命的一个基本思路就是把需要的目录名加到源文件名字的前面或者后面。首先拿到实际的文件名可以使用 basename 命令,如果想拿到目录名则可以使用 dirname 命令。

for i in `ls */*.bam`
do
cp $i ./bamfile/$(dirname $i)_$(basename $i)
done

本文作者:思考问题的熊

版权声明:本博客所有文章除特别声明外,均采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。

熊言熊语会员通讯「4321X」是一个免费的订阅服务。
每周为你会推荐 4 篇生物信息或者医学相关文献,分享 3 个我过去一周的思考,介绍 2 个我喜欢的工具,同时提出 1 个问题供我们交流,而 X 则代表不固定的 one more thing。可以点击这里进行订阅。


· 分享链接 https://kaopubear.top/blog/2020-05-30-linuxfile3tips/