如何捕获命令的第一列值?

时间:2017-03-14 18:17:15

标签: bash shell

我是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命令,还是有更好的方法来执行命令并循环结果?

3 个答案:

答案 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'
  • 变量$.包含当前行号