我是shell脚本新手。我正在尝试编写一个脚本,假设运行一个命令并使用for循环捕获输出的第一列并进行进一步处理。
命令:tst get files
此命令的输出类似于
NAME COUNT ADMIN
FileA.txt 30 adminA
FileB.txt 21 local
FileC.txt 9 local
FileD.txt 90 adminA
以下是我到目前为止所尝试的内容: UPDATED 也想运行其他命令
#!/bin/bash
for f in $(tst get files)
do
echo "FILE :[${f}]"
tst setprimary ${f} && tst get dataload
done
我看到的输出类似于
FILE :[NAME]
FILE :[COUNT]
FILE :[ADMIN]
FILE :[FileA.txt]
FILE :[30]
FILE :[adminA]
FILE :[FileB.txt]
FILE :[21]
FILE :[local]
FILE :[FileC.txt]
FILE :[9]
FILE :[local]
FILE :[FileD.txt]
FILE :[90]
FILE :[adminA]
我正在寻找类似
的输出FILE :[FileA.txt]
FILE :[FileB.txt]
FILE :[FileC.txt]
FILE :[FileD.txt]
我应该在shell脚本中修改哪些内容才能捕获NAME列值?我是否在for循环中正确执行了tst get files命令,还是有更好的方法来执行命令并循环结果?
答案 0 :(得分:3)
编辑(Samuel Kirschner):你可以完全不使用for循环,只需使用awk
打印你感兴趣的行
tst get files | awk 'NR > 1 {print "FILE :[" $1 "]"}'
如果你想出于某些原因保留for循环,只是在跳过标题时从行中提取文件名,你有几个选择。 awk可能是最容易的,因为NR
内置变量(计算行数)和自动字段拆分(例如,$1
指的是行中的第一个字段),但您可以使用{{ 1}}和sed
。
您可以使用cut
获取第一列(在跳过第一行时使用任何空格字符作为分隔符)或awk 'NR > 1 {print $1}'
。请注意,sed 1d | cut -d$'\t' -f1
是文字制表符字符的特定于bash的语法,如果您的文件使用空格填充而不是使用制表符分隔字段,则无法使用$'\t'
示例。
即
sed ... | cut ...
或
#!/bin/bash
for f in $(tst get files | awk 'NR > 1 {print $1}')
do
echo "FILE :[${f}]"
done
以避免#!/bin/bash
for f in $(tst get files | sed 1d | cut -d$'\t' -f1)
do
echo "FILE :[${f}]"
done
循环中不必要的拆分。最好将IFS设置为循环体外部的特定内容,以防止for
被分解。
'a file with whitespace.txt'
答案 1 :(得分:1)
你可以这样做:
tst get files | awk 'NR > 1 { printf "FILE :[%s]\n", $1 }'
更新:按照以下评论解答扩展问题:OP:
while read -r file _; do
tst setprimary "$file" && tst get dataload
done < <(tst get files)
答案 2 :(得分:1)
或perl:
tst ... | perl -lanE 'say "File: [$F[0]]" if $.>1'
$.
包含当前行号