如何检查目录中的每个文件并要求用户在 csh shell 中执行操作

如何检查目录中的每个文件并要求用户在 csh shell 中执行操作

我想用这个脚本执行的操作是

  1. 读取目录中每个文件的名称(不带基数)
  2. 对于每个文件,询问用户是否要执行操作(例如移动目录中的文件)
  3. 执行或不执行该操作。

    我的 while 循环和读取输入有问题。我尝试过这个:

    #! /bin/csh -f set DIR = 'pwd' find $DIR -name * -exec basename {} \; | while read filename do read -p $filename" (y or n?)" choice if ($choice = "y") then <> endif end

但我收到错误:

find: `basename' terminated by signal 13.

我也在考虑再次使用一段时间来扩展用户的输入,直到给出“是”或“否”,但这是一个二阶问题。

答案1

bash即使您使用#!-line 指定,您的 shell 代码的一部分看起来也像代码cshcsh没有read命令,这就是您收到signal 13错误的原因。

信号 13 是 PIPE 信号,当进程尝试写入死管道(没有人从另一端读取的管道)时,它会被发送到进程。管道已死,因为循环read中的调用失败while。它失败了,因为它在csh.

如果 csh如果有一个read命令,你的循环将获取文件名,但你不会有任何方式知道在哪里这些文件名属于(在哪个子目录中),因为您从中删除了目录路径。因此,您将无法对它们做太多事情。


最简单的这样做的方法是find向用户询问问题:

find . -type f -ok some-action '{}' ';'

some-action在使用路径名作为参数执行实用程序之前,这将要求确认每个路径名。它会询问将为给定路径名执行的完整命令行,因此这并不完全是您想要的。

另请注意,指定-type f将查找所有常规文件,而您的-name '*'测试将总是适用于所有类型的文件,包括目录。我还使用.(当前目录)作为 的顶级目录find,这似乎是您想要对DIR变量执行的操作。

要手动要求用户输入每个文件,同时正确处理路径名,最简单的方法是执行以下操作

find . -type f -exec sh -c '
    for pathname do
        printf "process %s (%s)?\n" "${pathname##*/}" "$pathname" >&2
        read answer
        case $answer in [Nn]*) continue; esac

        printf "processing %s...\n" "$pathname" >&2
        # process "$pathname" here
    done' sh {} +

这假设有一个sh类似 shell,并将生成sh -c由 找到的批量路径名find。内部 shell 脚本会询问用户是否愿意处理每个单独的路径名。如果用户回答以n(不区分大小写)开头的单词,则将考虑下一个路径名。

"${pathname##*/}"代码中的位相当于删除"$( basename "$pathname" )"最后$pathname一个斜杠之前的所有内容(包括最后一个斜杠)。

find命令充当一种路径名生成器对于for内部脚本中的 -loop,因此while无需将路径名或文件名通过管道传输到 -loop。

有关的:

相关内容