多个位置参数分配" cut"命令

时间:2017-04-05 20:40:30

标签: bash

首先,我想提前感谢你们所有人,我希望有朝然成为你们的一部分。所以我有一个文件,它是5个参数长的行列表。如

Bob:Wilson:Nebraska:34:yes

我需要在BASH中编写一个程序,允许我水平查看标准输出,并允许我调用文件中的文本行,如

$sh filename.sh 1
Bob
Tom
Dave
etc..

$sh filename.sh 1 3 4 2
Bob:Nebraska:34:Wilson
Tom:Iowa:27:Anderson
etc..

到目前为止我写的是

cut -d : -f$1,$2,$3,$4,$5 somefile.txt | paste -s

问题是如果用户在sh filename.sh之后放入少于5个参数我得到错误代码。用户不需要输入5但最多可以调用5.

3 个答案:

答案 0 :(得分:0)

awk救援!

awk -F: -v c="$1 $2 $3 $4 $5" 'BEGIN {n=split(c,a," ")} 
                                     {for(i=1;i<n;i++) printf "%s", $a[i] FS; 
                                      printf "%s\n", $a[n]}' file

如果您需要澄清,请尝试告诉我。

答案 1 :(得分:0)

仅展开现有参数

IFS=,
cut -d : -f"$*" somefile.txt

$*扩展为1st parameter $IFS 2nd parameter $IFS ... $IFS last parameter,即{{1}如果给出了两个参数,$1,$2如果给出了三个,依此类推。

允许重新排列

上面的命令有问题:$1,$2,$3无法重新排列列。 cut相当于cut -f1,2。见rearrange columns using cut。因此,我们使用cut -f2,1代替。

如果参数为awk,那么我们需要以下filename.sh 1 3 4 2命令:

awk

awk -F: -v OFS=: '{ print $1, $3, $4, $2 }' somefile.txt 设置字段分隔符以读取文件。 -F设置输出的字段分隔符。 -v OFS=:表示»打印第一个字段,然后打印第三个字段,...... «。请注意,print $1, $3, ... 不是脚本的第一个参数,而是由awk解释的文字字符串。

我们使用与以前相同的技巧从给定参数构建'$1' - 命令。

awk

IFS=, awk -F: -v OFS=: "{ print ${*/#/$} }" somefile.txt 为每个参数添加${*/#/$}。扩展名为$ $ 1st parameter , $ 2nd parameter ... , , {{1 }}

答案 2 :(得分:0)

我个人总是避免使用shell脚本进行文本处理。有一些更好的工具,例如sedawkperl等等。这就是我在纯粹的bash中做的事情,因为这似乎是你正在寻找的东西(*):

#!/bin/bash
#file: script.sh

for line in $(<somefile.txt); do
   array=( ${line//:/ } )
   counter=1
   for elem in $@; do
      echo -n "${array[$elem-1]}"
      [ $counter -ne $# ] && echo -n ":"
      ((counter++))
   done
   echo
done

(*):不要被语法高亮显示混淆,语法高亮显示将$#之后的所有内容识别为注释(灰色文本)。在示例脚本中,它在语法上都是正确的。

<强>解释

该脚本读取somefile.txt,将每一行拆分为:个字符,并将结果字段/元素存储在数组array中。然后它按照脚本参数($@)指定的顺序输出字段。

以下是输出,具体如何:

$ ./script.sh 1
Bob
Tom

$ ./script.sh 1 3 4 2
Bob:Nebraska:34:Wilson
Tom:Iowa:27:Anderson

还请注意以下内容:

在您的示例中,您可能使用Bourne Shell(sh)而不是bash执行脚本。但上述脚本需要bash,因为它使用substring replacement功能。