如何编写一个读取目录中所有文件名并在文件名中找到特定字符串的shell脚本?
Posted
技术标签:
【中文标题】如何编写一个读取目录中所有文件名并在文件名中找到特定字符串的shell脚本?【英文标题】:How to write a shell script that reads all the file names in the directory and finds a particular string in file names? 【发布时间】:2017-11-19 17:50:20 【问题描述】:我需要一个 shell 脚本来在文件中查找一个字符串,如下所示: 文件名_1.00_r0102.tar.gz 然后从多次出现的值中选择最大值。
我对文件名的“1.00”部分感兴趣。 我可以使用以下命令在 UNIX shell 中单独获取这部分:
find /directory/*.tar.gz | cut -f2 -d'_' | cut -f1 -d'.'
1
2
3
1
find /directory/*.tar.gz | cut -f2 -d'_' | cut -f2 -d'.'
00
02
05
00
问题是这个字符串有多个文件:
文件名_1.01_r0102.tar.gz
文件名_2.02_r0102.tar.gz
文件名_3.05_r0102.tar.gz
文件名_1.00_r0102.tar.gz
我需要选择具有 FileName_("最高值")_r0102.tar.gz 的文件
但由于我是 shell 脚本的新手,所以我无法弄清楚如何在脚本中处理这些多个实例。
我为整数部分想出的脚本如下:
#!/bin/bash
for file in /directory/*
file_version = find /directory/*.tar.gz | cut -f2 -d'_' | cut -f1 -d'.'
done
OUTPUT: file_version:command not found
请帮助。 谢谢!
【问题讨论】:
这不是答案,只是尝试识别语法错误,以便下次避免它们:1)您需要在 for 循环中使用do
:for .... ;do .... ;done
2)当您设置了一个变量,等号周围不能有空格:file_version=5
, not file_version = 5
3) 要设置一个包含命令输出的变量,您需要 command substitution:@987654329 @ 4) 不是语法错误,但引用变量赋值的 RHS 是个好主意:file_version="$(command)"
.
以上建议很好,但不要让我们为您检查脚本的语法,学习使用shellcheck.net。你知道head
和tail
cmds。如果您可以强制对输出进行排序,那应该会有所帮助。祝你好运。
非常感谢,@Nick!
@shellter 这是我第一次编写脚本。 shellcheck.net 真的很有用。谢谢!!
【参考方案1】:
如果你只想要最新的版本号:
cd /path/to/files
printf '%s\n' *r0102.tar.gz | cut -d_ -f2 | sort -n -t. -k1,2 |tail -n1
如果你想要文件名:
cd /path/to/files
lastest=$(printf '%s\n' *r0102.tar.gz | cut -d_ -f2 | sort -n -t. -k1,2 |tail -n1)
printf '%s\n' *$lastest_r0102.tar.gz
【讨论】:
【参考方案2】:您可以尝试以下方法,查找所有匹配的文件,对文件名进行排序,获取该列表中的最后一个,然后从文件名中提取版本。
#!/bin/bash
file_version=$(find ./directory -name "FileName*r0102.tar.gz" | sort | tail -n1 | sed -r 's/.*_(.+)_.*/\1/g')
echo $file_version
【讨论】:
【参考方案3】:我已经尝试过,这值得在你需要的脚本行下工作。
echo `ls ./*.tar.gz | sort | sed -n /[0-9]\.[0-9][0-9]/p|tail -n 1`;
【讨论】:
【参考方案4】:在查找实际文件名之前无需解析文件名的版本号。使用 GNU ls
的 -v
(文本中自然排序的(版本)数字)选项:
ls -v FileName_[0-9.]*_r0102.tar.gz | tail -1
【讨论】:
以上是关于如何编写一个读取目录中所有文件名并在文件名中找到特定字符串的shell脚本?的主要内容,如果未能解决你的问题,请参考以下文章