bash 使用“查找”返回没有扩展名的文件名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41965415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using 'find' to return filenames without extension
提问by Siavosh Mahboubian
I have a directory (with subdirectories), of which I want to find all files that have a ".ipynb" extension. But I want the 'find' command to just return me these filenames without the extension.
我有一个目录(带有子目录),我想在其中找到所有具有“.ipynb”扩展名的文件。但我希望“查找”命令只返回这些文件名而不带扩展名。
I know the first part:
我知道第一部分:
find . -type f -iname "*.ipynb" -print
But how do I then get the names without the "ipynb" extension? Any replies greatly appreciated...
但是我如何在没有“ipynb”扩展名的情况下获得名称?任何答复不胜感激...
回答by kenorb
To return only filenames without the extension, try:
要仅返回没有扩展名的文件名,请尝试:
find . -name "*.ipynb" -execdir sh -c 'printf "%s\n" "${0%.*}"' {} ';'
or:
或者:
find "$PWD" -type f -iname "*.ipynb" -execdir basename {} .ipynb ';'
or:
或者:
find . -type f -iname "*.ipynb" -exec basename {} .ipynb ';'
however invoking basename
on each file can be inefficient, so @CharlesDuffysuggestion is:
然而,basename
在每个文件上调用可能效率低下,所以@CharlesDuffy 的建议是:
find . -name '*.ipynb' -exec bash -c 'printf "%s\n" "${@%.*}"' _ {} +
or:
或者:
find . -iname '*.ipynb' -execdir basename -s '.sh' {} +
Using +
meansthat we're passing multiple files to each bash instance, so if the whole list fits into a single command line, we call bash only once.
Using+
意味着我们将多个文件传递给每个 bash 实例,因此如果整个列表适合单个命令行,我们只调用 bash 一次。
To print full path and filename (without extension) in the same line, try:
要在同一行中打印完整路径和文件名(不带扩展名),请尝试:
find . -name "*.ipynb" -exec sh -c 'printf "%s\n" "${0%.*}"' {} ';'
or:
或者:
find "$PWD" -type f -iname "*.ipynb" -print | grep -o "[^\.]\+"
To print full path and filename on separate lines:
要在单独的行上打印完整路径和文件名:
find "$PWD" -type f -iname "*.ipynb" -exec dirname "{}" ';' -exec basename "{}" .ipynb ';'
回答by eewanco
Here's a simple solution:
这是一个简单的解决方案:
find . -type f -iname "*.ipynb" | sed 's/\.ipynb$//1'
回答by user1934428
回答by Shakiba Moshiri
Perl One Liner
what you wantfind . | perl -a -F/ -lne 'print $F[-1] if /.*.ipynb/g'
Perl One Liner
你想要什么find . | perl -a -F/ -lne 'print $F[-1] if /.*.ipynb/g'
Then not your code
what you do not wantfind . | perl -a -F/ -lne 'print $F[-1] if !/.*.ipynb/g'
然后不是你的代码
你不想要的find . | perl -a -F/ -lne 'print $F[-1] if !/.*.ipynb/g'
NOTE
In Perlyou need to put extra .
. So your pattern would be .*.ipynb
注意
在Perl 中,您需要添加额外的.
. 所以你的模式是.*.ipynb
回答by niglesias
If there's no occurrence of this ".ipynb" string on any file name other than a suffix, then you can try this simpler way using tr
:
如果后缀以外的任何文件名上都没有出现此“.ipynb”字符串,那么您可以尝试使用这种更简单的方法tr
:
find . -type f -iname "*.ipynb" -print | tr -d ".ipbyn"
回答by Diego
If you don't know that the extension is or there are multiple you could use this:
如果您不知道扩展名是或有多个扩展名,您可以使用它:
find . -type f -exec basename {} \;|perl -pe 's/(.*)\..*$//;s{^.*/}{}'
and for a list of files with no duplicates (originally differing in path or extension)
以及没有重复的文件列表(最初的路径或扩展名不同)
find . -type f -exec basename {} \;|perl -pe 's/(.*)\..*$//;s{^.*/}{}'|sort|uniq
回答by bentocin
Another easy way which uses basename
is:
另一种简单的使用方法basename
是:
find . -type f -iname '*.ipynb' -exec basename -s '.ipynb' {} +
Using +
will reduce the number of invocations of the command (manpage):
使用+
将减少命令(手册页)的调用次数:
-exec command {} +
This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of '{}' is allowed within the command, and (when find is being invoked from a shell) it should be quoted (for example, '{}') to protect it from interpretation by shells. The command is executed in the starting directory. If any invocation with the `+' form returns a non-zero value as exit status, then find returns a non-zero exit status. If find encounters an error, this can sometimes cause an immediate exit, so some pending commands may not be run at all. For this reason -exec my-command ... {} + -quit may not result in my-command actually being run. This variant of -exec always returns true.
-exec 命令 {} +
-exec 操作的这种变体对选定的文件运行指定的命令,但命令行是通过在每个选定的文件名后附加来构建的;命令的总调用次数将远小于匹配文件的数量。命令行的构建方式与 xargs 构建其命令行的方式非常相似。命令中只允许出现一个 '{}' 实例,并且(当 find 是从 shell 调用时)它应该被引用(例如,'{}')以保护它不被 shell 解释。该命令在起始目录中执行。如果任何带有“+”形式的调用返回一个非零值作为退出状态,则 find 返回一个非零退出状态。如果 find 遇到错误,这有时会导致立即退出,所以一些挂起的命令可能根本不会运行。因此 -exec my-command ... {} + -quit 可能不会导致 my-command 实际运行。-exec 的这个变体总是返回真。
Using -s
with basename
runs accepts multiple filenames and removes a specified suffix (manpage):
使用-s
with basename
running 接受多个文件名并删除指定的后缀 ( manpage):
-a, --multiple
support multiple arguments and treat each as a NAME
-s, --suffix=SUFFIX
remove a trailing SUFFIX; implies -a
-a, --multiple
支持多个参数并将每个参数视为 NAME
-s, --suffix=后缀
删除尾随的后缀;暗示 -a
回答by jjisnow
I found this in a bash oneliner that simplifies the process without using find
我在 bash oneliner 中发现了这个,它在不使用 find 的情况下简化了过程
for n in *.ipynb; do echo "${n%.ipynb}"; done
回答by V. Michel
If you need to have the name with directory but without the extension :
如果您需要名称带目录但不带扩展名:
find . -type f -iname "*.ipynb" -exec sh -c 'f=$(basename .ipynb);d=$(dirname );echo "$d/$f"' sh {} \;