我在目录中有一个 bash 脚本./
。该目录包含目录output
.其中output
有文件,例如...
Alabama.txt
U.S. Virgin Islands.txt
如何循环遍历文件output
并打印以下输出
Alabama
U.S. Virgin Islands
答案1
for pathname in output/*.txt; do
basename "$pathname" .txt
done
该basename
实用程序获取路径名并从中删除所有目录部分,只留下最终的文件名部分。它还接受一个字符串作为可选的第二个参数。该字符串将从给定路径名的末尾被修剪掉。
我们basename
在所有名称匹配的循环中使用output/*.txt
来删除output/
路径名的一部分并删除.txt
文件名后缀。这仅留下输出的文件名的“茎”。
您可以使用内置标准参数替换来实现相同的效果:
for pathname in output/*.txt; do
name=${pathname#output/}
printf '%s\n' "${name%.txt}"
done
这对扩展为的每个路径名执行两个参数替换output/*.txt
;一个用于删除初始output/
子字符串,第二个用于删除尾随子.txt
字符串。
output
如果存在目录中可能没有带有文件名后缀的文件的风险.txt
,那么您可能需要设置nullglob
shell 选项(使用shopt -s nullglob
)。这将阻止上述循环运行一次,否则它们会执行一次(使用output/*.txt
中的未扩展模式$pathname
)。
dotglob
如果您想匹配目录中的隐藏名称,您可能还需要设置shell 选项。
答案2
用zsh
而不是bash
:
print -rC1 -- output/*.*(N:t:r)
其中,在olumn上print -rC1 --
打印其参数r
aw ,并且是 glob 限定符,用于启用(如果没有匹配文件,则 glob 将扩展为空),是类似 csh 的修饰符,用于获取文件的ail 和oot(删除目录部分)和扩展)。1
C
(N:t:r)
N
nullglob
:t
:r
t
r
D
如果您还想包含隐藏文件,请添加glob 限定符(在这种情况下,您可能需要更改*.*
为?*.*
以确保这些隐藏文件具有扩展名。
使用任何 shell,但使用 的 GNU 实现basename
,并假设您感兴趣的所有文件都没有隐藏并且具有.txt
扩展名,output
其中至少包含一个这样的文件,并且文件列表不太大,以免要超过execve()
args+env 的大小限制,您还可以执行以下操作:
basename -as.txt output/*.txt
特别是对于bash
(GNU shell),以及使用 的 GNU 实现sed
,您还可以执行以下操作:
(
shopt -s dotglob nullglob
printf '%s\0' output/?*.* |
LC_ALL=C sed -z 's:.*/::; s/\.[^.]*$//' |
tr '\0' '\n'
)
zsh
包含隐藏文件的近似值。