简体   繁体   中英

bash print first to nth column in a line iteratively

I am trying to get the column names of a file and print them iteratively. I guess the problem is with the print $i but I don't know how to correct it. The code I tried is:

#! /bin/bash
for i in {2..5}
do
  set snp = head -n 1 smaller.txt | awk '{print $i}'
  echo $snp
done

Example input file:

ID Name Age Sex State Ext
1  A    12   M    UT  811
2  B    12   F    UT  818

Desired output:

Name 
Age
Sex 
State
Ext

But the output I get is blank screen.

You'd better just read the first line of your file and store the result as an array:

read -a header < smaller.txt

and then printf the relevant fields:

printf "%s\n" "${header[@]:1}"

Moreover, this uses only, and involves no unnecessary loops.

Edit. To also answer your comment, you'll be able to loop through the header fields thus:

read -a header < smaller.txt
for snp in "${header[@]:1}"; do
    echo "$snp"
done

Edit 2. Your original method had many many mistakes. Here's a corrected version of it (although what I wrote before is a much preferable way of solving your problem):

for i in {2..5}; do
    snp=$(head -n 1 smaller.txt | awk "{print \$$i}")
    echo "$snp"
done
  • set probably doesn't do what you think it does.
  • Because of the single quotes in awk '{print $i}' , the $i never gets expanded by .
  • This algorithm is not good since you're calling head and awk 4 times, whereas you don't need a single external process.

Hope this helps!

您可以使用awk本身进行打印:

awk 'NR==1{for (i=2; i<=5; i++) print $i}' smaller.txt

The main problem with your code is that your assignment syntax is wrong. Change this:

set snp = head -n 1 smaller.txt | awk '{print $i}'

to this:

snp=$(head -n 1 smaller.txt | awk '{print $i}')

That is:

  • Do not use set . set is for setting shell options, numbered parameters, and so on, not for assigning arbitrary variables.
  • Remove the spaces around = .
  • To run a command and capture its output as a string, use $(...) (or `...` , but $(...) is less error-prone).

That said, I agree with gniourf_gniourf's approach.

Here's another alternative; not necessarily better or worse than any of the others:

for n in $(head smaller.txt)
do
  echo ${n}
done

somthin like

  for x1 in $(head -n1 smaller.txt );do 
      echo $x1
  done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM