从标准输出管道中使用两次参数

时间:2016-06-22 23:57:25

标签: shell scripting

我有一个命令行工具,它接收两个参数:

TOOL  arg1 -o arg2

我想用arg1和arg2提供的相同参数调用它,为了让我这么容易,我想我会这样做:

each <arg1_value> | TOOL $1 -o $1

但这不起作用,$ 1不会被替换,但会在命令行末尾添加一次。

一个明确的例子,表演:

cp fileA fileA

返回错误 fileA且fileA相同(未复制) 执行时:

echo fileA | cp $1 $1

返回以下错误: 用法:cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file        cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory

任何想法?

7 个答案:

答案 0 :(得分:4)

如果您想使用xargs,[ - I]选项可能会有所帮助:

-I replace-str
              Replace  occurrences of replace-str in the initial-arguments with names read from standard input.  Also, unquoted blanks do not terminate input items; instead the separa‐
              tor is the newline character.  Implies -x and -L 1.

这是一个简单的例子:

mkdir test && cd test && touch tmp
ls | xargs -I '{}' cp '{}' '{}'

返回错误 cp:tmp和tmp是同一个文件

答案 1 :(得分:2)

如果您使用xargs标志,-I实用程序将复制其输入流以替换其参数中的所有占位符:

$ echo hello | xargs -I XXX echo XXX XXX XXX
hello hello hello

占位符XXX(可以是任何字符串)将替换为输入流到xargs的整行输入,因此如果我们给它两行:

$ printf "hello\nworld\n" | xargs -I XXX echo XXX XXX XXX
hello hello hello
world world world

您可以在工具中使用它:

$ generate_args | xargs -I XXX TOOL XXX -o XXX

其中generate_args是为您的工具生成参数的脚本,命令或shell函数。

原因

each <arg1_value> | TOOL $1 -o $1
除了each不是我认识的命令之外,

不起作用,$1扩展为当前shell或函数的第一个位置参数。

以下内容有效:

set - "arg1_value"
TOOL "$1" -o "$1"

因为在调用工具之前设置$1的值。

答案 2 :(得分:1)

$1,$2...$N仅对bash脚本可见,以解释这些脚本的参数,并且不会按照您希望的方式工作。管道将stdout重定向到stdin,而不是您正在寻找的。

如果您只想要一个单行,请使用类似

的内容
  

ARG1 =你好&amp;&amp;工具$ ARG1 $ ARG1

答案 3 :(得分:1)

将管道中的数据加倍,并使用 sed xargs 将其一次性输入 two 命令:

seq 5 | sed p | xargs -L 2 echo 

输出:

1 1
2 2
3 3
4 4
5 5

答案 4 :(得分:1)

使用GNU parallel四次使用STDIN,打印乘法表:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("MovieCell", forIndexPath: indexPath) as! MovieCell
    let movie:Movie = movieList[indexPath.row]
    let vm = HomeViewModel(withMovie: movie)

    // fill cell with data
    vm.title.producer.startWithNext { (newValue) in
        cell.titleLabel.text = newValue
    }

    vm.description.producer.startWithNext { (newValue) in
        cell.descriptioLabel.text = newValue
    }

    vm.image.producer.startWithNext { (newValue) in
        if let newValue = newValue {
            cell.imageView?.image = newValue as UIImage
        }
    }

    return cell
}

输出:

seq 5 | parallel 'echo {} \* {} = $(( {} * {} ))'

答案 5 :(得分:1)

可以使用awk封装工具:

$ echo arg1 arg2 | awk '{ system("echo TOOL " $1 " -o " $2) }'
TOOL arg1 -o arg2

删除echo来电中的system()TOOL应按照要求执行:

echo arg1 arg2 | awk '{ system("TOOL " $1 " -o " $2) }'

答案 6 :(得分:1)

您可以使用sh -c重新运行shell以执行变量扩展。 -c接受一个参数,该命令在shell中运行,执行扩展。 sh的下一个参数将被解释为$ 0,$ 1等,以便在-c中使用。例如:

sh -c 'echo $1, i repeat: $1' foo bar baz将打印执行echo $1, i repeat: $1,其中$ 1设置为bar($ 0设置为foo,$ 2设置为baz),最后打印{{1} }}