【问题标题】:Map list of filenames as option values for command将文件名列表映射为命令的选项值
【发布时间】:2020-07-28 07:55:14
【问题描述】:

我有很多文件,想用它们的名字作为命令的参数,这样命令就变成了

<command> <option> <file1> <option> <file2> ...

对于每个文件名,我想在其前面加上选项名称。我不知道有多少个文件。我怎样才能做到这一点? bash/shell 有类似map 的东西吗?

文件存在,所以我会使用find 获取名称,或者如果我确定文件名,可能会使用ls,所以我正在寻找类似xargs 的东西

ls -1q <pattern> | xargs <command> ...

但不是 xargs 所做的(将其转换为每个文件的一个命令),我想要一个带有多个参数的单个命令,并在所有文件名之前插入 &lt;option&gt;

在我的具体示例中,我想将未知数量的覆盖数据文件与一个命令组合:

lcov -o total.coverage -a <file1> -a <file2> ... 

这是在 Makefile 中,但我更喜欢“标准”外壳方法。

【问题讨论】:

  • 列表来自哪里?
  • I have list of filenames 文件名是如何存储的?在 bash 数组中?在一个文件中?在变量中?在make变量中?在 bash 变量中?变量中的条目是否由换行符分隔?它们是零终止的吗?通过其他角色?请发布一些代码。 Does bash/shell have something similar to map? 是的,bash 有关联数组..
  • 他们不是来自任何地方。编辑得更清楚。
  • The files exists so I would get the names using lsdo not parse ls output
  • 然后至少使用ls -1。 (ls -1q)

标签: bash shell dictionary options


【解决方案1】:
fileslist=( $(cd /path/to/files/you/want/ ;find -maxdepth 1 -printf "%P\n" | xargs -0) )
for t in ${fileslist[@]} 
do
commandtoperform $t
done

【讨论】:

  • -printf "%P\n" | xargs -0 没有意义。只需printf "%P\n"
【解决方案2】:

在查找文件的同时也打印选项,使用零分隔流来处理所有可能的文件名:

find . -maxdepth 1 -mindepth 1 -type f -printf "-a\0%p\0" | xargs -0 lcov -o total.coverage

与换行符作为列表元素的分隔符相同:

find . -maxdepth 1 -mindepth 1 -type f -printf "-a\n%p\n" | xargs -d '\n' lcov -o total.coverage

【讨论】:

    【解决方案3】:

    试试这个:

    files=(pattern)
    # This will expand the [pattern], and put all the files in [files] variables
    
    lcov -o total.coverage ${files[@]/#/-a }
    # ${files[@]/#/-a } replaces the beginning of each element in files with [-a ],
    # meaning prepend [-a ]
    # For more information, see section [${parameter/pattern/string}] in
    # https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
    

    假设您的文件名中没有特殊字符(如空格)。

    【讨论】:

    • 完美!如果你再解释一下,我会接受你的回答。
    • 糟糕。当然,在 Makefile 中不起作用(bash 而不是sh,这是make 使用的标准shell)。但因为我想要一个通用的解决方案,它仍然是一个候选者;-)
    • 我认为您可以在 Makefile 中重新定义 SHELL。
    • 是的,但我不想那样做。
    【解决方案4】:

    也许是这个?

    function multi_lcov(){
      files_params=($@)
      lcov ${files_params[@]}
    }
    
    multi_lcov "$(ls | sed -r 's/(.*)/\-a \1/g')"
    

    【讨论】:

      【解决方案5】:

      你可以这样做:

      ls <pattern> |sed "s/^/-optionItself /g"|xargs
      

      因此在每个文件名前附加-optionItself,然后将其发送给xargs

      我相信还有很多其他方法可以实现这一点,这是最简单且最接近您使用的方法。

      【讨论】:

      • 这也不错。它是标准外壳,可在 Makefile 中运行。
      猜你喜欢
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 2020-03-30
      相关资源
      最近更新 更多