在bash中的每个“通配符”参数前添加一些文本

时间:2018-09-27 06:23:14

标签: bash wildcard wildcard-expansion

一个简单的示例:mybin *.txt将扩展为mybin a.txt b.txt c.txt

但是我正在寻找一种简单的解决方案,以扩展到类似mybin --conf a.txt --conf b.txt --conf c.txt的地方。

有内置的吗?最简单的方法是什么?

5 个答案:

答案 0 :(得分:0)

一些棘手的解决方案:

eval mybin "--conf\ {`echo *.txt|tr -s " " ,`}"

答案 1 :(得分:0)

所有txt文件

eval mybin "$(printf -- '--conf %q ' *.txt)"

如果仅用于某些txt文件

eval mybin '--conf "'{a,b,c}.txt'"'

也许我们应该使用包装函数。这不是内置的解决方案,但是如果文件名包含空格或特殊字符,它会比前两个命令更有效。

功能mybinw

function mybinw() {
  declare -a mybin_opts

  for file in "$@"; do
    mybin_opts+=(--conf "$file")
  done

  mybin "${mybin_opts[@]}"
}

测试:

mybin

#!/bin/bash

for q in "$@"; do
  echo "=> $q"
done

创建一些txt文件,某些文件名包含空格或特殊字符

touch {a,b,c,d,efg,"h h"}.txt 'a(1).txt' 'b;b.txt'

对于所有txt文件:

eval mybin "$(printf -- '--conf %q ' *.txt)"
=> --conf
=> a(1).txt
=> --conf
=> a.txt
=> --conf
=> b;b.txt
=> --conf
=> b.txt
=> --conf
=> c.txt
=> --conf
=> d.txt
=> --conf
=> efg.txt
=> --conf
=> h h.txt

对于某些txt文件:

eval mybin '--conf "'{a,b,c,"h h"}.txt'"'
=> --conf
=> a.txt
=> --conf
=> b.txt
=> --conf
=> c.txt
=> --conf
=> h h.txt

使用包装函数

touch 'c"c.txt'

mybinw *.txt
=> --conf
=> a(1).txt
=> --conf
=> a"b.txt
=> --conf
=> a.txt
=> --conf
=> b;b.txt
=> --conf
=> b.txt
=> --conf
=> c"c.txt
=> --conf
=> c.txt
=> --conf
=> d.txt
=> --conf
=> efg.txt
=> --conf
=> h h.txt

答案 2 :(得分:0)

find是我的朋友:

mybin $(find /wherever/ -name '*.txt' -printf '--conf %p ')

答案 3 :(得分:0)

# usage mix command switch args ...
mix(){
        p=$1; shift; q=$1; shift; c=
        i=1; for a; do c="$c $q \"\${$i}\""; i=$((i+1)); done
        eval "$p $c"
}

mix mybin --conf *.txt

这可移植到任何POSIX shell中,而不仅仅是bash,并且能够处理带有空格,特殊字符等的文件名:

$ qecho(){ for a; do echo "{$a}"; done; }
$ touch 'a;b' "a'b" "a\\'b" 'a"b' 'a\"b' '(a b)' '(a    b)' 'a
b'
$ mix qecho --conf *
{--conf}
{(a    b)}
{--conf}
{(a b)}
{--conf}
{a
b}
{--conf}
{a"b}
{--conf}
{a'b}
{--conf}
{a;b}
{--conf}
{a\"b}
{--conf}
{a\'b}

答案 4 :(得分:0)

set -- *.txt

for thing do
    shift
    set -- "$@" --conf "$thing"
done

mybin "$@"

这将使用位置参数列表($@)来保存扩展的glob模式。然后,我们遍历这些项目并通过在每个项目之前插入$@来修改--conf。然后可以使用此列表调用mybin实用程序。

代码中的引用是有意的,以防止外壳程序在空格上拆分任何字符串,并阻止扩展任何文件名glob(如果它们出现在*.txt匹配的文件名的适当部分中。)

特定于bash的变体形式:

files=( *.txt )

for thing in "${files[@]}"; do
    args+=( --conf "$thing" )
done

mybin "${args[@]}"

以上两种情况的更小变化。首先是/bin/sh

set --
for thing in *.txt; do
    set -- "$@" --conf "$thing"
done

mybin "$@"

然后bash

for thing in *.txt; do
    args+=( --conf "$thing" )
done

mybin "${args[@]}"

作为shell函数:

delim_run () {
    cmd=$1
    delim=$2

    shift 2

    for thing do
        shift
        set -- "$@" "$delim" "$thing"
    done

    "$cmd" "$@"
}

您将能够做到

delim_run mybin --conf *.txt