将bash中的定界文本文件解析为命令参数


10

我有一个文本文件,像这样拆分:

field1,field2,field3 
xield1,xield2,xield3 
dield1,dield2,dield3 
gield1,gield2,gield3

这些列中的每一列都是程序的参数,我希望每行都调用该程序

我希望循环,就像:

for $i in file
    command $field2 -x $field3 -PN -$field1 >> output
done

在bash中完成这样的事情的最佳方法是什么?


字段数是否恒定?
Joseph R.

@JosephR。是的,他们总是3
Dean

Answers:


7
while IFS=, read xx yy zz;do
    echo $xx $yy $zz
done < input_file

如果字段数恒定,这应该可以工作。而不是echo使用您的命令。


谢谢,我只是尝试这样做,但它似乎只适用于第一行。一旦命令成功执行,它不会尝试下一个命令;如果失败,它将尝试下一个命令...
Dean

你是成功还是失败?您的命令做什么?
coffeMug ​​2013年

我猜想他正在运行的命令正在读取“ comd”命令之前的标准输入。
–plugwash

4

您应该使用whileread内置:

while IFS= read -r line;do
    fields=($(printf "%s" "$line"|cut -d',' --output-delimiter=' ' -f1-))
    command "${fields[1]}" -x "${fields[2]}" ... # ${fields[1]} is field 2
done < your_file_here

如何运作

  • cut语句采用该行并将其在由指定的定界符上分割-d
  • --output-delimiter是,分隔符cut将用于显示所选字段,这里我们选择的空间,所以我们可以把不同领域到数组fields
  • 最后,我们希望所有字段(从字段1到结尾)-f1-都在起作用。
  • 现在,你必须存放在数组变量的不同领域fields,您可以访问任何你想要的特定领域的语法${field[number]},其中number一个比你少,因为数组索引所需的实际场数是从零开始的猛砸。

注意

  • 如果您的任何字段包含空格,这将失败。

对于恒定数量的字段

您可以改为执行类似于1_CR的答案

while IFS= read -r line;do
    IFS=, read -r field1 field2 field3 <<-EOI
    $line
    EOI
    command "$field2" -x "$field3" ... 
done < your_file_here

上面的代码看起来比较吵杂,但它可以在任何POSIX兼容的shell中运行,而不仅仅是Bash。


它不是在读取我遇到问题的文件,而是将行分成几列。
院长

@Dean是的,对不起。我没有注意。现在就做。
Joseph R.

@Dean请参阅更新后的答案。我将在短期内添加一个解释。
Joseph R.

@JosephR。,可以通过IFSread调用中设置适当的值来避免使用外部工具进行拆分
iruvar 2013年

@ 1_CR我知道,谢谢。我只是想知道:)
Joseph R.

1

您可以通过适当设置read将每一行拆分成一个数组。,IFS

while IFS=, read -r -a input; do
 printf "%s\n" "${input[0]}" "${input[1]}"
done < input.txt

因此,在上面的示例中,您可以使用索引从0开始的每个数组元素。


1

这种awk单线可做您想要的:

awk -F, '{cmd="echo " $2 " -x " $3 " -PN " $1 ">> output";  system(cmd)}' f.txt

echo用您的命令和f.txt您要迭代的文件替换。

简要说明:-F,将设置,为分隔符。cmd构建命令并system(cmd)调用命令。


1

也可以使用gnu sed。

sed infile -e 's!^\([^,]*\),\([^,]*\),\([^,]*\)$!command \1 -x \2 -PN \3!e' >> output

注意s命令使用e选项

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.