gpt4 book ai didi

linux - bash:展开参数列表并将其传递给查找 - 转义/空格 hell

转载 作者:太空宇宙 更新时间:2023-11-04 09:32:26 25 4
gpt4 key购买 nike

我想检查文件夹中的文件并删除其中的一些文件。一个条件是保留特定类型的所有文件(例如 .txt),并保留所有具有第一次搜索名称但具有不同扩展名([第一次搜索的名称].)的文件。应删除目录中的所有其他文件。

这可以通过 find 轻松实现。 -type f -not -name xxx 命令。但是,我想为每个自动找到的 [name of first search] 填充 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: unknown predicate `-\'

如果我使用 sed 命令 (' ' -> '\') 或

find: paths must precede expression: - Usage: find [-H] [-L] [-P] [-Olevel] [-D [help|tree|search|stat|rates|opt|exec] [path...] [expression]

如果我评论 sed 行。

bash -x 显示了以下执行的命令:

没有 sed 命令:

find . -type f -not -name ''\''Text' - here - or - there*'\'''

使用 sed 命令:

find . -type f -not -name ''\''Text\' '-\' 'here\' '-\' 'or\' 'there*'\'''

这甚至可以通过 find 实现吗?我还尝试在 find 命令中转义 $find_list 但没有成功。

最佳答案

使用数组,而不是字符串。

#!/bin/bash
# ^-- must be /bin/bash, not /bin/sh, for this to work

excludes=( )
for filename in *.txt; do
excludes+=( -not -name "${filename%.txt}" )
done

find . -type f -not -name '*.txt' "${excludes[@]}" -exec rm -f '{}' +

要了解其工作原理,请参阅 BashFAQ #50 .


现在,如果你想与 /bin/sh 兼容,而不仅仅是 bash,那么将其封装在一个函数中,这样你就可以覆盖参数列表(这是唯一可用的数组)而无需丢弃脚本的全局参数:

delete_except_textfiles() {
local filename 2>/dev/null ||: "local keyword not in POSIX, ignore if not present"
set --
for filename in *.txt; do
set -- "$@" -not -name "${filename%.txt}"
done
find . -type f -not -name '*.txt' "$@" -exec rm -f '{}' +
}
delete_except_textfiles

关于linux - bash:展开参数列表并将其传递给查找 - 转义/空格 hell ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29975377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com