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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:41:19  来源:igfitidea点击:

Using 'find' to return filenames without extension

linuxbashshellunixsh

提问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 basenameon 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

find . -type f -iname "*.ipynb" | grep -oP '.*(?=[.])'

The -o flag outputs only the matched part. The -P flag matches according to Perl regular expressions. This is necessary to make the lookahead(?=[.])work.

-o 标志只输出匹配的部分。-P 标志根据 Perl 正则表达式匹配。这是使前瞻(?=[.])工作所必需的。

回答by Shakiba Moshiri

Perl One Liner
what you want
find . | 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 want
find . | 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 basenameis:

另一种简单的使用方法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 -swith basenameruns accepts multiple filenames and removes a specified suffix (manpage):

使用-swith basenamerunning 接受多个文件名并删除指定的后缀 ( 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 {} \;