我有以下目录结构:
├── 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
它的等...但是,还有一种替代方法:它称为{.}
{/}
find
fd
(有时fdfind
)如果你使用那个你可以运行:
fd -e json -x mv -- {} {.}
fd -e json
表示查找带有json
扩展名的文件,-x
代表“执行”,然后{}
是{.}
文件名和不带扩展名的文件名的占位符(与 相同的字符串替换gnu parallel
)。
请注意,您需要在 和 的旧版本中引用( as {}
) '{}'
,并且 在那些加上, ,的情况下,/具有特殊含义。rc
akanga
fish
{.}
csh
tcsh
zsh -o braceccl
{
}
另请注意,默认情况下fd
(与 相反find
)会忽略隐藏文件(名称以 a 开头的文件.
或位于名称以 a 开头的目录下的文件,.
以及.ignore
/ .gitignore
/ .git/ignore
/ .fdignore
... 文件中提到的文件;请参阅-H
/ --hidden
、-I
/ --no-ignore
、-u
/--unrestricted
选项更改它)以及名称无法解码为 UTF-8 的名称(无论区域设置如何)。