首先,我想提前感谢你们所有人,我希望有朝然成为你们的一部分。所以我有一个文件,它是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.
答案 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脚本进行文本处理。有一些更好的工具,例如sed
,awk
或perl
等等。这就是我在纯粹的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功能。