一行 bash 脚本中的文件扩展名列表
List of extensions of filenames in bash script in one line
我目前有以下代码行:
ls /some/dir/prefix* | sed -e 's/prefix.//' | tr '\n' ' '
哪个实现了我想要它做的事情:
- 获取以前缀开头的文件列表
- 从每个字符串中删除路径和前缀
- 删除换行符并替换为空格以供以后处理。
例如:
/some/dir/prefix.hello
/some/dir/prefix.world
应该变成
hello world
但我觉得有更好的方法来做到这一点。有没有更好的方法在一行中完成此操作?
awk 的一种方法:
ls /some/dir/prefix* | awk -F"." '{printf "%s ", } END {print ""}'
它可能符合 "nicer" 因为只有一个命令输出通过管道传输?!
这是一个只使用内置函数的两行代码:
fnames=(some/dir/prefix*)
echo "${fnames[@]##*.}"
工作原理如下:
fnames=(some/dir/prefix*)
创建一个包含所有以 prefix
开头的文件的数组,并避免解析 ls
带来的所有问题
echo "${fnames[@]##*.}"
是两个参数扩展的组合:${fnames[@]}
打印所有数组元素,##*.
部分删除以 .
结尾的任何内容的最长匹配项来自每个数组元素,只留下扩展
如果您执意要单行,只需将两个命令与 &&
连接起来即可。
不推荐将 ls
输出传递给外部程序,以下 bash 解决方案可能对您有所帮助。
for file in prefix*; do echo ${file##*.}; done
现在也添加了一种非线性形式的解决方案。
for file in prefix*
do
echo ${file##*.}
done
这是实现此目的的非常简单的 Awk 单行代码:
awk -F. '{[=10=]=FILENAME; printf $NF" "; nextfile}' /some/dir/prefix*
它基本上做了以下事情:
-F.
:设置字段分隔符FS
为.
。这样 $NF
代表扩展名。
[=17=]=FILENAME
: 忽略当前记录并将其设置为FILENAME
,重新解析所有内容。
print $NF; nextfile
: 打印扩展名并转到下一个文件。
这个问题是文件仍然读取当前文件的一条记录。如果该文件为空,这将失败。
要使用空文件进行此操作,您可以使用 gawk
扩展名 BEGINFILE
awk -F. 'BEGINFILE{[=11=]=FILENAME; printf $NF" "; nextfile}' /some/dir/prefix*
或者您可以遍历所有参数:
awk -F. 'BEGIN{for(i in ARGV){[=12=]=ARGV[i]; printf $NF" "};exit}' /some/dir/prefix*
我目前有以下代码行:
ls /some/dir/prefix* | sed -e 's/prefix.//' | tr '\n' ' '
哪个实现了我想要它做的事情:
- 获取以前缀开头的文件列表
- 从每个字符串中删除路径和前缀
- 删除换行符并替换为空格以供以后处理。
例如:
/some/dir/prefix.hello
/some/dir/prefix.world
应该变成
hello world
但我觉得有更好的方法来做到这一点。有没有更好的方法在一行中完成此操作?
awk 的一种方法:
ls /some/dir/prefix* | awk -F"." '{printf "%s ", } END {print ""}'
它可能符合 "nicer" 因为只有一个命令输出通过管道传输?!
这是一个只使用内置函数的两行代码:
fnames=(some/dir/prefix*)
echo "${fnames[@]##*.}"
工作原理如下:
fnames=(some/dir/prefix*)
创建一个包含所有以prefix
开头的文件的数组,并避免解析ls
带来的所有问题
echo "${fnames[@]##*.}"
是两个参数扩展的组合:${fnames[@]}
打印所有数组元素,##*.
部分删除以.
结尾的任何内容的最长匹配项来自每个数组元素,只留下扩展
如果您执意要单行,只需将两个命令与 &&
连接起来即可。
不推荐将 ls
输出传递给外部程序,以下 bash 解决方案可能对您有所帮助。
for file in prefix*; do echo ${file##*.}; done
现在也添加了一种非线性形式的解决方案。
for file in prefix*
do
echo ${file##*.}
done
这是实现此目的的非常简单的 Awk 单行代码:
awk -F. '{[=10=]=FILENAME; printf $NF" "; nextfile}' /some/dir/prefix*
它基本上做了以下事情:
-F.
:设置字段分隔符FS
为.
。这样$NF
代表扩展名。[=17=]=FILENAME
: 忽略当前记录并将其设置为FILENAME
,重新解析所有内容。print $NF; nextfile
: 打印扩展名并转到下一个文件。
这个问题是文件仍然读取当前文件的一条记录。如果该文件为空,这将失败。
要使用空文件进行此操作,您可以使用 gawk
扩展名 BEGINFILE
awk -F. 'BEGINFILE{[=11=]=FILENAME; printf $NF" "; nextfile}' /some/dir/prefix*
或者您可以遍历所有参数:
awk -F. 'BEGIN{for(i in ARGV){[=12=]=ARGV[i]; printf $NF" "};exit}' /some/dir/prefix*