I have data as following :

enter image description here

What i need to get is the OS_NATIVE_NAME of a particular DEVICE.

I know one way is to print its column value using:

awk '{print $*col_num*}'

But the column number for this OS_NATIVE_NAME is not fixed. This is because, other fields like STATUS can have values different (could be multiple sometime), which is causing a problem of not having fixed column number for the OS_NATIVE_NAME, which is the required data for my tests.

How can i grep that particular column's content??

  • Can you assume that the columns begin in fixed character positions, or does that have to be determined dynamically from the header line? – dubiousjim Sep 25 '15 at 6:53
  • Columns format & order is fixed. Is that what you are asking? – amitam Sep 25 '15 at 6:54
  • Is the output tab delimited or space delimited? – chaos Sep 25 '15 at 6:58
  • space limited. I tried like this also. # vxdisk -e list | awk '{print $1"\t\t\t" $6}' DEVICE OS_NATIVE_NAME disk_0 invalid disk_1 invalid intel_ssd0_0 sdc So you can see here, i am getting different data from different columns. – amitam Sep 25 '15 at 6:59
  • BTW: Can you please add the example data as code blocks? With an image it's hard to do test cases. – chaos Sep 25 '15 at 7:20

With awk:

awk 'NR==1{for(i=1;i<NF;i++){if($i=="OS_NATIVE_NAME"){s=index($0,$i); l=index($0,$(i+1))-s}}}
 $1=="disk_0"{print substr($0,s,l)}' file
  • NR==1 if it's the first line (the header line), NR is awks internal variable for the current line number being processed.
    • for(i=1;i<NF;i++) loop trough the fields. NF is awks internal variable for the number of fields in the current line.
    • $i=="OS_NATIVE_NAME" since, we're looping trough each field, check if the field value equals OS_NATIVE_NAME
    • s=index(...) find the position of the start of the field and save it for later. index() is awks string function to get the position of the occurence of a string (here the value of $i, hence OS_NATIVE_NAME) in another string (here $0, hence the whole line).
    • l=index(...)-s get the length of the field and save it for later: same priciple as before, but to get the length we must substract s from it.
  • $1=="disk_0" find the DEVICE you are searching in the first field (disk_0 in the example). $1 represents the first field.
    • {print substr($0,s,l)} finally print for each line, the string started at position s, with length l. substr() is awks string function to cut a string (here $0; the whole line) from position s with length l (the two varibale we prevously extracted while processing line 1)

Prints (regardless of where the field is in the input):

  • I thought this but this will not work all the time, because position of OS_NATIVE_NAME string is not same as that of its data. right?? – amitam Sep 25 '15 at 7:13
  • @AmitM I think I don't understand, can you give an example? Why should the position of OS_NATIVE_NAME not be the same as its data? – chaos Sep 25 '15 at 7:15
  • Its working (y) but i couldn't understand it completely. – amitam Sep 25 '15 at 7:26
  • Can you elaborate it little bit more... -thanks – amitam Sep 25 '15 at 7:38
  • @AmitM I edit the answer to be mor specific. Hope it's clear now =) – chaos Sep 25 '15 at 7:48

One easy solution:

data=$(vxdisk -e list)
devices=$(sed 's/ .*//' <<< "$data")
# I'm just guessing that the relevant column starts in column 80
os_native_name=$(cut -c80- <<< "$data")
for dev in $devices; do let row++; if [[ "$dev" = disk_1 ]]; then break; fi; done
# now we know our desired data is on the row'th line of os_native_name
# you can retrieve it for instance with
sed -n "$row p" <<< "$os_native_name"
  • This isnt working.. – amitam Sep 25 '15 at 7:14
  • It worked in my tests, can you give more information? – dubiousjim Sep 25 '15 at 7:15
  • Can you tell me how can i upload image here? Data is not getting pasted properly.. – amitam Sep 25 '15 at 7:18
  • You can't upload an image to comments. – dubiousjim Sep 25 '15 at 7:19

Try below command:

vmdisk -e list | awk 'NR==1 { for(i=1;i<=NF;i++) { ix[$i] = i } } NR>1 { print $ix["OS_NATIVE_NAME"] }'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.