find exec - 仅使用 {} 中的部分文件名

find exec - 仅使用 {} 中的部分文件名

我有以下目录结构:

├── file1.json
├── file2.json
└── file3.json

我想去掉.json后缀。我知道最好的方法可能是rename命令或使用 a for-loop,但我想知道find命令是否也可以做到这一点。

例如附加.json很简单,我执行以下命令:

find . -type f -name 'file?' -exec mv {} {}.json \;

但现在我想反转名称过程,我该如何做到这一点find

答案1

您的初始过程通过附加.json.例如file1(匹配模式file?)被重命名为file1.json.反向比较复杂,需要一点shell脚本处理

find . -type f -name 'file?.json' -exec sh -c 'mv -- "$1" "${1%.json}"' _ {} \;

sh将为 找到的每个文件调用find。通常,可以创建更高效​​的流程,而复杂性几乎不会增加:

find . -type f -name 'file?.json' -exec sh -c 'for f in "$@"; do mv -- "$f" "${f%.json}"; done' _ {} +

两种解决方案都使用 POSIX shell replacement ${var%suffix},它返回一个与 相对应的值,并从其值的末尾删除了$var文字文本(如果可能)。suffix

var=hello.txt
echo "${var%.txt}"    # "hello" because ".txt" is removed
echo "${var%.zzz}"    # "hello.txt" because there is no ".zzz" suffix
echo "$var"           # "hello.txt" because the variable itself is unchanged

答案2

嗯,说明书说得很清楚了:

字符串“{}”被当前正在处理的文件名替换[...]

find不是提供额外的占位符来操作文件名,例如使用gnu parallel它的等...但是,还有一种替代方法:它称为{.}{/}findfd(有时fdfind)如果你使用那个你可以运行:

fd -e json -x mv -- {} {.}

fd -e json表示查找带有json扩展名的文件,-x代表“执行”,然后{}{.}文件名和不带扩展名的文件名的占位符(与 相同的字符串替换gnu parallel)。

请注意,您需要在 和 的旧版本中引用( as {}) '{}',并且 在那些加上, ,的情况下,/具有特殊含义。rcakangafish{.}cshtcshzsh -o braceccl{}

另请注意,默认情况下fd(与 相反find)会忽略隐藏文件(名称以 a 开头的文件.或位于名称以 a 开头的目录下的文件,.以及.ignore/ .gitignore/ .git/ignore/ .fdignore... 文件中提到的文件;请参阅-H/ --hidden-I/ --no-ignore-u/--unrestricted选项更改它)以及名称无法解码为 UTF-8 的名称(无论区域设置如何)。

相关内容