How to capture first column values of a command?

I am new to shell scripting. I am trying to write a script that is suppose to run a command and use for loop to capture first column of the output and do further processing.

command: tst get files

output of this command is something like

NAME COUNT ADMIN FileA.txt 30 adminA FileB.txt 21 local FileC.txt 9 local FileD.txt 90 adminA 

Here is what I have tried so far : UPDATED also want to run additional commands

#!/bin/bash for f in $(tst get files) do echo "FILE :[${f}]" tst setprimary ${f} && tst get dataload done 

the output I am seeing is something like

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] 

I am looking for an output something like

FILE :[FileA.txt] FILE :[FileB.txt] FILE :[FileC.txt] FILE :[FileD.txt] 

What should I modify in the shell script to only capture NAME column values? Am I executing the tst get files command correctly in the for loop or is there a better way to execute a command and loop thru the results?

3 Answers

EDIT (Samuel Kirschner): you can do without the for loop entirely and just use awk to print the lines you're interested in

tst get files | awk 'NR > 1 {print "FILE :[" $1 "]"}' 

If you want to keep the for loop for some reason and just extract the file name from the lines while skipping the header, you have a few choices. Awk is probably the easiest because of the NR builtin variable (which counts lines) and automatic field-splitting ($1 refers to the first field in the line, for instance), but you can use sed and cut as well.

You can use awk 'NR > 1 {print $1}' to get the first column (using any whitespace character as a delimiter while skipping the first line) or sed 1d | cut -d$'\t' -f1. Note that $'\t' is bash-specific syntax for a literal tab character, if your file is padded with spaces rather than using tabs to delimit fields, you can't use the sed ... | cut ... example.

i.e.

#!/bin/bash for f in $(tst get files | awk 'NR > 1 {print $1}') do echo "FILE :[${f}]" done 

or

#!/bin/bash for f in $(tst get files | sed 1d | cut -d$'\t' -f1) do echo "FILE :[${f}]" done 

to avoid unnecessary splitting in the for loop. It's best to set IFS to something specific outside the loop body to prevent 'a file with whitespace.txt' from being broken up.

OLD_IFS=IFS IFS=$'\n\t' for f in $(tst get files | sed 1d | cut -d$'\t' -f1) do echo "FILE :[${f}]" done 
2

You can just do:

tst get files | awk 'NR > 1 { printf "FILE :[%s]\n", $1 }' 

Update: To answer extended problem as per comments below by OP:

while read -r file _; do tst setprimary "$file" && tst get dataload done < <(tst get files) 
6

Or perl:

tst ... | perl -lanE 'say "File: [$F[0]]" if $.>1' 
  • the variable $. contains the current line number

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like