一行中bash脚本中文件名扩展名的列表

时间:2018-06-25 13:20:40

标签: bash sed filenames ls tr

我目前有以下代码行:

ls /some/dir/prefix* | sed -e 's/prefix.//' | tr '\n' ' '

哪些功能可以实现我想要的功能:

  • 获取以前缀开头的文件列表
  • 从每个字符串中删除路径和前缀
  • 删除换行符并替换为空格以供以后处理。

例如:

/some/dir/prefix.hello
/some/dir/prefix.world

应该成为

hello world

但是我觉得有一种更好的方法。有没有更好的方法可以在一行中做到这一点?

4 个答案:

答案 0 :(得分:4)

这里有两个内胆,仅使用内置的内胆就可以做到:

fnames=(some/dir/prefix*)
echo "${fnames[@]##*.}"

这是它的工作方式:

  • fnames=(some/dir/prefix*)创建一个数组,其中所有文件均以prefix开头,并避免了解析ls带来的所有问题
  • echo "${fnames[@]##*.}"是两个参数扩展的组合:${fnames[@]}打印所有数组元素,而##*.部分从每个参数中删除所有以.结尾的最长匹配项数组元素,仅保留扩展名

如果您想一口气,只需将两个命令与&&结合使用。

答案 1 :(得分:1)

不建议将ls输出传递给外部程序,以下bash解决方案可能会帮助您。

for file in prefix*; do echo ${file##*.}; done

现在也添加一种非衬套形式的解决方案。

for file in prefix*
do
   echo ${file##*.}
done

答案 2 :(得分:1)

这是一个非常简单的Awk单行代码,可以实现此目的:

awk -F. '{$0=FILENAME; printf $NF" "; nextfile}' /some/dir/prefix*

它基本上执行以下操作:

  • -F.:将字段分隔符FS设置为.。这样$NF表示扩展名。
  • $0=FILENAME:忽略当前记录并将其设置为FILENAME,以这种方式重新解析所有内容。
  • print $NF; nextfile:打印扩展名并转到下一个文件。

此问题是文件仍然读取当前文件的记录。如果该文件为空,则将失败。

要使用空文件进行此操作,可以使用gawk扩展名BEGINFILE

awk -F. 'BEGINFILE{$0=FILENAME; printf $NF" "; nextfile}' /some/dir/prefix*

或者您也可以遍历所有参数:

awk -F. 'BEGIN{for(i in ARGV){$0=ARGV[i]; printf $NF" "};exit}' /some/dir/prefix*

答案 3 :(得分:0)

使用awk的一种方法:

ls /some/dir/prefix* | awk -F"." '{printf "%s ", $2} END {print ""}'

它可能被认为是“更精细的”,因为只有一条命令通过输出管道传输了?!