开发者

Get next field/column width awk

开发者 https://www.devze.com 2023-04-02 09:00 出处:网络
I have a dataset of the following structure: 1234 4334 8677 3753 3453 4554 4564 4834 3244 3656 2644 0474

I have a dataset of the following structure:

1234 4334 8677 3753 3453 4554
4564 4834 3244 3656 2644 0474
...

I would like to: 1) search for a specific value, eg 4834 2) return the following field (3244)

I'm quite new to awk, but realize it is a simple operation. I have created a bash-script that asks the user for the input, and attempts to return the following field. But I can't seem to get around scoping in AWK. How do I parse the input value to awk?

#!/bin/bash
read input

cat data.txt | awk '
 for (i=1;i<=NF;i++) {
  if ($i==input) {       
   print $(i+1)
  }
 }
}'

Cheers and thanks in advance!

UPDATE Sept. 8th 2011

Thanks for all the replies.

1) It will never happen that the last number of a ro开发者_StackOverflow社区w is picked - still I appreciate you pointing this out.

2) I have a more general problem with awk. Often I want to "do something" with the result found. In this case I would like to output it to xclip - an application which read from standard input and copies it to the clipboard. Eg: $ echo Hi | xclip

Unfortunately, echo doesn't exist for awk, so I need to return the value and echo it. How would you go about this?


#!/bin/bash
read input

cat data.txt | awk '{
 for (i=1;i<=NF;i++) {
  if ($i=='$input') {       
   print $(i+1)
  }
 }
}'


Don't over think it!

You can create an array in awk with the split command:

split($0, ary)

This will split the line $0 into an array called ary. Now, you can use array syntax to find the particular fields:

awk '{
    size = split($0, ary)
    for (i=1; i < size ;i++) {
        print ary[i]
    }
    print "---"
}' data.txt

Now, when you find ary[x] as the field, you can print out ary[x+1].

In your example:

awk -v input=$input '{
   size = split($0, ary)
   for (i=1; i<= size ;i++) {
       if ($i == ary[i]) {       
           print ary[i+1]
       }
  }
}' data.txt

There is a way of doing this without creating an array, but it's simply much easier to work with arrays in situations like this.

By the way, you can eliminate the cat command by putting the file name after the awk statement and save creating an extraneous process. Everyone knows creating an extraneous process kills a kitten. Please don't kill a kitten.


You pass shell variable to awk using -v option. Its cleaner/nicer than having to put quotes.

awk -v input="$input" '
   for(i=1;i<=NF;i++){
      if ($i == input ){
         print "Next value: " $(i+1)
      }
   }
' data.txt

And lose the useless cat.


Here is my solution: delete everything up to (and including) the search field, then the field you want to print out is field #1 ($1):

awk '/4834/ {sub(/^.* * 4834 /, ""); print $1}' data.txt
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号