【发布时间】:2026-02-06 01:20:10
【问题描述】:
我想检查文件夹中的文件并删除其中一些。一个条件是保留某种类型的所有文件(例如 .txt),并保留所有具有第一次搜索名称但扩展名不同的文件([第一次搜索的名称].)。应该删除目录中的所有其他文件。
这可以通过find . -type f -not -name xxx 命令轻松实现。但是,我想为自动找到的每个 [第一次搜索的名称] 填充 find 命令。
为此,我编写了这个小脚本
#!/bin/bash
while read filename; do
filename=$(echo $filename | sed 's/\ /\\\ /g')
filename=\'$filename*\'
file_list=$file_list" -not -name $filename"
done <<<"$(ls *.txt | sed 's/.txt//g')"
find . -type f $file_list -print0| while read -d $'\0' FILE
do
rm -f "$FILE"
done
$file_list 很好地填充了相应的数据,但是 find 失败说:
查找:未知谓词`-\'
如果我使用 sed 命令 (' ' -> '\ ') 或
find:路径必须在表达式之前:- 用法:find [-H] [-L] [-P] [-Olevel] [-D [help|tree|search|stat|rates|opt|exec] [path...] [表达]
如果我评论 sed 行。
bash -x 显示以下执行的命令:
没有 sed 命令:
找到 . -type f -not -name ''\''Text' - 这里 - 或 - 那里*'\'''
使用 sed 命令:
找到 . -type f -not -name ''\''文本\' '-\' '这里\' '-\' '或\' '那里*'\'''
这甚至可以通过 find 实现吗?我还尝试在 find 命令中转义 $find_list,但没有成功。
【问题讨论】:
-
您无法将引号添加到work that way 的字符串参数中。但你不需要。引用变量扩展,它将是正在运行的命令的一个参数。也 don't parse the output from ls 只需使用 glob(在这种情况下使用
echo或者不要打扰read循环,只需在 globfor file in *.txt上使用for循环)。 -
另外,
$'\0'只是在 bash 中编写''的一种更复杂的方式,因为 bash 将内容存储在 C 字符串中,而 NUL 字节终止 C 字符串。 (-d ''作为read的参数正确指示了 NUL 终止符,因为 0 字节字符串的第一个字节是它的 NUL 终止符)。
标签: linux bash shell find escaping