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

Vin*_*nod 4 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
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所尝试过的:更新也想运行其他命令

#!/bin/bash

for f in $(tst get files)
do
    echo "FILE :[${f}]"
    tst setprimary ${f} && tst get dataload
done
Run Code Online (Sandbox Code Playgroud)

我看到的输出是这样的

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]
Run Code Online (Sandbox Code Playgroud)

我正在寻找类似的输出

FILE :[FileA.txt]
FILE :[FileB.txt]
FILE :[FileC.txt]
FILE :[FileD.txt]
Run Code Online (Sandbox Code Playgroud)

我应该在 shell 脚本中修改什么才能仅捕获 NAME 列值?我是否在 for 循环中正确执行 tst get files 命令,或者是否有更好的方法来执行命令并循环结果?

Gre*_*bet 6

编辑(Samuel Kirschner):您可以完全不用 for 循环,只用awk它来打印您感兴趣的行

tst get files | awk 'NR > 1 {print "FILE :[" $1 "]"}'
Run Code Online (Sandbox Code Playgroud)

如果您出于某种原因想保留 for 循环,并在跳过标题的同时从行中提取文件名,您有几种选择。awk 可能是最简单的,因为它有NR内置变量(对行进行计数)和自动字段分割($1例如,指行中的第一个字段),但您也可以使用sed和。cut

您可以使用awk 'NR > 1 {print $1}'来获取第一列(使用任何空白字符作为分隔符,同时跳过第一行)或sed 1d | cut -d$'\t' -f1. 请注意,这$'\t'是 bash 特定的文字制表符语法,如果您的文件用空格填充而不是使用制表符来分隔字段,则无法使用该sed ... | cut ...示例。

IE

#!/bin/bash

for f in $(tst get files | awk 'NR > 1 {print $1}')
do
    echo "FILE :[${f}]"
done
Run Code Online (Sandbox Code Playgroud)

或者

#!/bin/bash

for f in $(tst get files | sed 1d | cut -d$'\t' -f1)
do
    echo "FILE :[${f}]"
done
Run Code Online (Sandbox Code Playgroud)

以避免for循环中不必要的分裂。最好将 IFS 设置为循环体外部的特定值,以防止'a file with whitespace.txt'被破坏。

OLD_IFS=IFS
IFS=$'\n\t'

for f in $(tst get files | sed 1d | cut -d$'\t' -f1)
do
    echo "FILE :[${f}]"
done
Run Code Online (Sandbox Code Playgroud)