我的文件的标题格式如下:
- 文件名01
- 文件07
- 文件标题8
文件名20
字符串和数字之间没有分隔符,并且每行的字符串字符不相等。
我只想输出文件名末尾的数字:
- 01
- 07
- 8
- 20
如果您只需要数字并且可能使用非字母数字字符,则可以使用sed
and [^0-9]
:
cat filename | sed 's|[^0-9]||g'
此外,如果存在重复的可能性并且顺序不是问题,您可以将其与sort
and结合使用uniq
:
cat filename | sed 's|[^0-9]||g' | sort | uniq
最后一个示例将为您提供在文件中找到的不同数字列表;但是,它确实尊重领先0
(即 - 8
!= 08
)。
更新(仅限 bash):
while read line; do \
echo ${line//[^0-9]/}; \
done < filename
尽管可读性较差(从我的角度来看),但它是实现相同目标的可行替代方案。此外,附加|sort | uniq
仍然适用于此示例。
编辑(文件扩展名)要保留文件扩展名(或第一个数字实例之后
的
任何文本),根据 OP 的评论,从命令中删除并添加 a将处理此问题:g
sed
*
cat filename | sed 's|[^0-9]*||'
这将保留第一个数字实例之后的所有内容,因此filename123.mp3
变为123.mp3
,并file123part456.txt
变为123part456.txt
。
如果您需要一个极其敏感的匹配来专门获取最后一个数字和任何现有的文件扩展名(可能没有文件扩展名,如原始问题所示),您可以使用grep
and-P
标志-o
:
grep -Po "[0-9]*(\..*)?" filename
这将导致filename123.mp3
返回123.mp3
,并file123part456.txt
返回456.txt
。该-P
标志指示将模式解释为 Perl 正则表达式;表示-o
仅返回匹配的部分行,而不是匹配的完整行。
使用 tr:
cat filename | tr -d [:alpha:]
我将grep -o
用于 OP 发布的问题:
grep -o '[0-9]*' filenames
在评论中,OP询问如何删除前导文本,在这种情况下使用:
sed 's/[^0-9]*//' filename
假设 ASCII 字符串
回声“HelloTrailz23”| tr -d '[AZ][az]'
如果您正在处理 unicode 文件名,那么所有的赌注都没有了。
这可能对您有用(GNU sed):
echo filename123onetwothree.999 | sed 's/.*[^0-9]\([0-9]*\)$/\1/'
999
这仅提取文件名末尾的数字。
为了使其普遍使用:
sed 's/.*[^[:digit:]]\([[:digit:]]*\)$/\1/' file
我总是喜欢使用 bash 的变量字符串操作。这是矫枉过正,但它很快就可以在命令行上运行。
for i in fileName01 file07 fileTitle8 fileName20 file123._mp3 ; do echo ${i//[!0-9]} ; done
结果:
01
07
8
20
1233
${i} 变量中的 //[!0-9] 在遍历列表时会删除每个字符串中除数字之外的所有内容。