从TSV文件执行命令和参数

时间:2015-04-04 01:33:24

标签: bash xargs

我有一个TSV文件,其中每一行代表一个命令和命令行参数。像这样:

ls      ~
cd      /home
cp      dir1    dir2

每行可能有不同数量的列。每个单元格可能包含空格,单引号和双引号。

执行此操作的好方法是什么?

2 个答案:

答案 0 :(得分:1)

使用Bash,读入IFS设置为选项卡的数组:

$ cat data
ls      ~
cd      /home
cp      dir1    dir2
al      a b       c  d  
$ vis -t -n data
ls^I~^J
cd^I/home^J
cp^Idir1^Idir2^J
al^Ia b^I  c  d  ^J
$ while IFS=$'\t' read -r -a xyz; do al "${xyz[@]}"; done < data
ls
~
cd
/home
cp
dir1
dir2
al
a b
  c  d  
$ while IFS=$'\t' read -r -a xyz; do al "${xyz[@]}"; done < data | vis -t -n
ls^J
~^J
cd^J
/home^J
cp^J
dir1^J
dir2^J
al^J
a b^J
  c  d  ^J
$

带有选项vis的{​​{1}}程序将标签打印为-t -n,将换行打印为^I(后跟换行符); ^J程序每行打印一个参数 - 它实际上等同于al(它实际上是一个非常简单的C程序,但结果是一样的。)

使用要执行的文件中的实际命令,您可以写:

printf "%s\n" "$@"

在我的机器上,我得到了:

while IFS=$'\t' read -r -a xyz; do "${xyz[@]}"; done < data

我使用了子shell,因为我不想将当前目录保留在主shell中,而且我没有$ (while IFS=$'\t' read -r -a xyz; do "${xyz[@]}"; done < data ) ls: ~: No such file or directory cp: dir1: No such file or directory a b c d $ 被复制到dir1 。请注意,shell没有对参数扩展的结果进行波浪扩展,因此dir2必须看到实际的波形符号,而不是我的主目录的值。固定波浪形扩展将是痛苦的 - 极度痛苦(见Tilde expansion in quotes)。它还意味着范围表示法如ls不会被扩展,并且不会扩展别名。请参阅Shell expansions了解会发生什么,不会发生什么。

答案 1 :(得分:0)

<强>解决方案:

ruby -ne 'require "shellwords"; system $_.chomp.split("\t").shelljoin'

证明:

以下是我们的测试脚本:cat printArguments.bash

#!/bin/bash
args=("$@")
for ((i=0; i < $#; i++)) {
   echo "argument $((i+1)): ${args[$i]}"
}

测试用例:

echo $'./printArguments.bash\t1\t\t3' | ruby -ne 'require "shellwords"; system $_.chomp.split("\t").shelljoin'

结果:

  

参数1:1

     

参数2:

     

论证3:3