【问题标题】:How to add argparse flags based on shell find results如何根据 shell 查找结果添加 argparse 标志
【发布时间】:2018-07-05 06:11:47
【问题描述】:

我有一个接受-f 标志的python 脚本,并附加了该标志的多种用途。

例如,如果我运行python myscript -f file1.txt -f file2.txt,我会得到一个文件列表files=['file1.txt', 'files2.txt']。这很好用,但我想知道如何自动使用 find 命令的结果来附加与文件一样多的 -f 标志。

我试过了:

find ./ -iname '*.txt' -print0 | xargs python myscript.py -f

但它只抓取第一个文件

【问题讨论】:

  • 使用glob.glob方法直接搜索python脚本中的所有文件名不是更容易吗?
  • 您是在问如何从 Python 执行此操作,还是从 shell 执行此操作?

标签: python shell argparse


【解决方案1】:

需要注意的是,如果文件多于单个命令行,这将失败(而xargs 将运行myscript.py 多次,每次都带有完整参数列表的一个子集):

#!/usr/bin/env bash

args=( )
while IFS= read -r -d '' name; do
  args+=( -f "$name" )
done < <(find . -iname '*.txt' -print0)

python myscript.py "${args[@]}"

如果您想安全地以允许任意数量的文件名的方式执行此操作,最好使用长格式选项 - 例如 --file 而不是 @987654325 @ -- 使用 = 分隔符允许将单个名称作为同一 argv 条目的一部分传递,从而防止 xargs 将文件名与其前面的印记分开:

#!/usr/bin/env bash
# This requires -printf, a GNU find extension
find . -iname '*.txt' -printf '--file=%p\0' | xargs -0 python myscript.py    

...或者,更便携(在 MacOS 上运行,尽管仍然需要一个可以处理 NUL 分隔读取的 shell(例如 bash)):

#!/usr/bin/env bash
# requires find -print0 and xargs -0; these extensions are available on BSD as well as GNU
find . -iname '*.txt' -print0 |
  while IFS= read -r -d '' f; do printf '--file=%s\0' "$f"; done |
  xargs -0 python myscript.py

【讨论】:

    【解决方案2】:

    您的标题似乎暗示您可以修改脚本。在这种情况下,请使用nargs(参数数量)选项为-f 标志提供更多参数:

    parser = argparse.ArgumentParser()
    parser.add_argument('--files', '-f', nargs='+')
    args = parser.parse_args()
    print(args.files)
    

    然后你就可以轻松使用你的 find 命令了:

    15:44 $ find . -depth 1 | xargs python args.py -f
    ['./args.py', './for_clint', './install.sh', './sys_user.json']
    

    否则,如果您无法修改脚本,请参阅@CharlesDuffy 的回答。

    【讨论】:

    • 你不能以这种方式安全地使用xargs——如果你的参数多于单个命令行的容量,你不知道它是在文件名之后还是在-f。 (此外,包含空格、文字引号、文字反斜杠等的文件名是不安全的)。
    • @CharlesDuffy 是的,我刚刚意识到这一点。认为我应该用这些警告编辑它或删除第二部分?
    • 就个人而言,如果有安全的替代方案,我不会展示不安全的做法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多