3

我需要获取文件夹中的所有文件扩展名类型。例如,如果目录的 ls 给出以下内容:

a.t  
b.t.pg  
c.bin  
d.bin  
e.old  
f.txt  
g.txt  

我应该通过运行脚本来得到这个

.t  
.t.pg  
.bin  
.old  
.txt  

我有一个 bash 外壳。

非常感谢!

4

3 回答 3

7

请参阅ParsingLS 上的 BashFAQ 条目,了解为什么其中许多答案是邪恶的。

以下方法避免了这个陷阱(顺便说一下,完全忽略了没有扩展名的文件):

shopt -s nullglob
for f in *.*; do
  printf '%s\n' ".${f#*.}"
done | sort -u

其中的优点:

  • 正确性:ls行为不一致,可能导致不适当的结果。请参阅顶部的链接。
  • 效率:最小化调用子进程的数量(只有一个,,sort -u如果我们想使用 Bash 4 的关联数组来存储结果,也可以删除)

仍然可以改进的地方:

  • 正确性:这将正确丢弃第一个之前的文件名中的换行符.(其他一些答案不会) - 但是第一个之后的换行符.将被视为单独的条目sort。这可以通过使用空值作为分隔符或通过上述 bash 4 关联数组存储方法来解决。
于 2012-04-16T15:36:05.063 回答
3

尝试这个:

ls -1 | sed 's/^[^.]*\(\..*\)$/\1/' | sort -u
  • ls列出文件夹中的文件,每行一个文件
  • sed魔术提取扩展
  • sort -u对扩展进行排序并删除重复项

sed 魔法读作:

  • s/ / /: 将第一个和第二个/之间的任何内容替换为第二个和第三个之间的任何内容/
  • ^: 匹配行首
  • [^.]: 匹配任何不是点的字符
  • *: 尽可能多地匹配它
  • \(\):记住这两个括号之间的匹配项
  • \.: 匹配一个点
  • .: 匹配任意字符
  • *: 尽可能多地匹配它
  • $: 匹配行尾
  • \1:这是括号之间匹配的内容
于 2012-04-16T15:40:25.360 回答
0

人们真的过于复杂了 - 特别是正则表达式:

ls | grep -o "\..*" | uniq

ls- 获取所有文件
grep -o "\..*"--o仅显示匹配项;"\..*"匹配第一个“。” & 之后的所有内容
uniq- 不要打印重复但保持相同的顺序

喜欢也可以排序,但排序与示例不符

这是运行它时发生的情况:

> ls -1
a.t
a.t.pg
c.bin
d.bin
e.old
f.txt
g.txt

> ls | grep -o "\..*" | uniq
.t
.t.pg
.bin
.old
.txt
于 2012-04-16T15:47:22.537 回答