英文:
Bash - For loop , exclude files with specific pattern in filename right before filetype
问题
以下是翻译好的内容:
我正在尝试运行一个for循环,但想要排除文件名中包含特定模式的文件。这是我正在使用的命令:
for file in /home/ubuntu/discovery/download/*![.en].mp4; do
我希望包括这个文件名:
Blub - S03E10 - Nervous Breakdown.mp4
但要排除这个文件名:
Blub - S03E10 - Nervous Breakdown.en.mp4
无法让它起作用。我做错了什么?
提前感谢。
英文:
I am trying to run a for loop but trying to exclude files with a specific pattern in the filename. This is the command I am using:
for file in /home/ubuntu/discovery/download/*![.en].mp4; do
I would like this filename to be included:
Blub - S03E10 - Nervous Breakdown.mp4
but this filename to be excluded
Blub - S03E10 - Nervous Breakdown.en.mp4
Can't get it to work. What am I doing wrong?
Thanks in advance
答案1
得分: 2
标准的全局匹配没有分组或分组否定运算符(虽然扩展版本有这些)。在你特定的上下文中,我会建议在循环内部过滤掉不想要的文件:
```shell
for file in /home/ubuntu/discovery/download/*.mp4; do
case $file in
*.en.mp4) continue;;
esac
# ...
done
而且这应该在任何 Bourne 家族的 shell 中都可以工作,不仅仅是 Bash。
<details>
<summary>英文:</summary>
> What am I doing wrong?
Standard globbing has no grouping or group negation operators (though the extended version has these). In your particular context, I would just filter out the unwanted files inside the loop:
for file in /home/ubuntu/discovery/download/*.mp4; do
case $file in
*.en.mp4) continue;;
esac
...
done
And that should work in any Bourne-family shell, not just Bash.
</details>
# 答案2
**得分**: 1
### 路径名扩展: *"match not"*, 启用 *`extglob`*:
> !(模式列表)
> 匹配除了给定模式之外的任何内容
尝试这样做:
for file in /home/ubuntu/discovery/download/!(*.en).mp4; do
...
<details>
<summary>英文:</summary>
### Pathname Expansion: *"match not"*, with *`extglob`* enabled:
> !(pattern-list)
> Matches anything except one of the given patterns
Try this:
for file in /home/ubuntu/discovery/download/!(*.en).mp4; do
...
</details>
# 答案3
**得分**: 1
shopt -s nullglob
for file in /home/ubuntu/discovery/download/*{[^n],[^e]n,[^.]en}.mp4
do
# ...
done
<details>
<summary>英文:</summary>
Another alternative could be:
shopt -s nullglob
for file in /home/ubuntu/discovery/download/*{[^n],[^e]n,[^.]en}.mp4
do
# ...
done
</details>
# 答案4
**得分**: 0
Another approach is to iterate over all files, skipping any that have undesirable name patterns. Just make sure to also handle the case where no files are found, because in that case, `file` is set equal to the glob pattern. Often you can handle that situation by verifying that the path in `file` actually exists (`-e "${file}"`).
```bash
for file in /home/ubuntu/discovery/download/*.mp4; do
[[ -e "${file}" && "${file}" != *.en.mp4 ]] || continue
echo ${file}
done
英文:
Another approach is to iterate over all files, skipping any that have undesirable name patterns. Just make sure to also handle the case where no files are found, because in that case, file
is set equal to the glob pattern. Often you can handle that situation by verifying that the path in file
actually exists (-e "${file}"
).
for file in /home/ubuntu/discovery/download/*.mp4; do
[[ -e "${file}" && "${file}" != *.en.mp4 ]] || continue
echo ${file}
done
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论