gpt4 book ai didi

以空格作为批量参数的文件名

转载 作者:行者123 更新时间:2023-11-29 09:44:38 24 4
gpt4 key购买 nike

如果我有一个文件列表,其中一些文件的名称中有空格,生成自:

find . -iname "*hs" | grep foo

如何将它们作为参数传递给单个进程,如 process name1 name2 ...

请注意,我想将所有文件名作为单独的参数传递给单个进程,因此标准的 for f in * 解决方案将不起作用

最佳答案

find . -iname "*hs*" -exec grep foo {} +

find . -iname "*hs*" -print0 | xargs -0 grep foo

两者都有效;第一个甚至可能更有效一点,除非 + 选项将更少的文件分组到命令行中而不是 xargs

如果您通过 shell 通配生成文件名,则:

grep foo *hs*

保留文件名中的空格。使用 ls 生成名称非常有问题。


过滤名称

The grep command was meant to filter the list of filenames before the bulk process, not to search the contents of the files themselves.

所以您想要名称同时匹配“hs”和“foo”?在这种情况下,您最好还是使用 find:

find . \( -iname "*hs*" -a -iname "*foo*" \) -exec grep foo {} +

使用find 的 bool 功能。

GNU grep 扩展 -Z-z

如果你做不到(你的 grep 正则表达式对于 find 来说太复杂了),那么你就会遇到困难,除非你有一个 (假设?)版本的 grep读取由空值分隔的“行”。

-Z, --null
Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name. For example, grep -lZ outputs a zero byte after each file name instead of the usual newline. This option makes the output unambiguous, even in the presence of file names containing unusual characters like newlines. This option can be used with commands like find -print0, perl -0, sort -z, and xargs -0 to process arbitrary file names, even those that contain newline characters.

这几乎就是我们想要的,但又不完全是。 POSIX 2008 getdelim()函数将是要使用的工具;为此,向 grep 添加一个 -z 选项,然后使用 grep -lzZ .... 来过滤 find 。 .. -print0 数据被送入 xargs -0 之前。

上面的引述来自 Mac OS X 10.7.5 的手册页,GNU grep 是版本 2.5.1。也许是更新版本的 GNU grep更有能力提供帮助?

你瞧,GNU grep 2.14 支持必要的选项:

-z, --null-data
Treat the input as a set of lines, each terminated by a zero byte (the ASCII NUL character) instead of a newline. Like the -Z or --null option, this option can be used with commands like ‘sort -z’ to process arbitrary file names.

find运行脚本

另一个不容忽视的选项是创建一个由 find 命令运行的脚本:

find . -iname "*hs*" -exec ./list-foo + 

list-foo 脚本可能在哪里:

for arg in "$@"
do
case "$arg" in
(*foo*) echo "$arg";; # This will still cause problems
esac
done

这标识了文件; echo 是次优的。也许您需要捕获数组中的名称,然后使用该数组调用最终命令:

array=( )
i=0
for arg in "$@"
do
case "$arg" in
(*foo*) array[$((i++))]="$arg";;
esac
done

if [ "$i" -gt 0 ]
then real_work "${array[@]}"
fi

real_work 是执行实际工作的程序(脚本?)。你可以在用完 list-foo 后扔掉它,除非你要一遍又一遍地做同样的过滤工作。


包含空格的全局名称

您可以通过转义空格来全局命名包含空格的名称:

rm -i -- *\ *

这将扩展为名称中仅包含空格的文件名,这有助于清理文件名包含为测试此问题的答案而创建的文件的目录。

关于以空格作为批量参数的文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14699653/

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