LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   awk regexp for uuid (https://www.linuxquestions.org/questions/programming-9/awk-regexp-for-uuid-804324/)

webhope 04-28-2010 03:37 AM

Quote:

Originally Posted by grail (Post 3950249)
The for loop is immediately exited as the array has no items to step through.
If you put an echo after done, this will be the only thing on screen.

Sorry bad question. I shoul to ask about dev variable. What if blkid nothing found. Awk returns what? Empty variable?

Code:

dev=$(blkid | grep $d |  awk 'BEGIN{FS=":"} {print $1}');
Edit - this works:
Code:

uuid=($(echo "$block_new" | awk 'BEGIN{RS="UUID="}/-/{gsub(/ .*/,"");print}'))
for d in ${uuid[@]}; do
  dev=$(blkid | grep $d |  awk 'BEGIN{FS=":"} {print $1}');
  if [[ -z $dev  ]]; then
  echo $dev
  else
  echo "uuid $uuid not found in list of devices"
  fi;
done


grail 04-28-2010 04:09 AM

Well I am curious, I am guessing it must be the way your machine is setup, but when I run blkid on the command line on its own
I get nothing returned.

Also, I am not sure if the awk is perhaps required seeing as man of blkid says:
Quote:

blkid -L label | -U uuid

-U uuid Look up one device that uses the uuid. For more details see the -L option.

webhope 04-28-2010 04:18 AM

Pherhaps I understand right.
I run su or sudo then run blkid else it says blkid not found
This operations under super user mode.
blkid I use offten to get informations like dev,uuid and label

blkid -U uuid searches the concrete device.

I god output:
uuid eab515e9-bc3e-4024-9f01-55fddaa0fb1c
e12487ff-6d6f-44c4-9e03-33f545b3b798 not found
That's right

However
I don't know how to make from e.g. /dev/sda3 the hd(0,2) ... Should I use awk to generate?

Edit:
But the last code I posted dosn't work right :-(
It should to show:
/dev/sda3
uuid e12487ff-6d6f-44c4-9e03-33f545b3b798 not found

1. contidion -z fail
2. the d var. is array not a string?

Edit:
Yeah the d var contains this sting or array
eab515e9-bc3e-4024-9f01-55fddaa0fb1c
e12487ff-6d6f-44c4-9e03-33f545b3b798
not separated... Bad too bad

grail 04-28-2010 04:38 AM

Thanks for the info, I too get results when using the sudo, but can use the -U option as normal user.
Yes it will return an array unless there is only one device attached (unlikely in modern systems)

Another issue you might face may be if someone has a RAID/LVM setup (like mine) and the output is even less useful:

Code:

grail@wetworks:~$ sudo blkid
[sudo] password for grail:
/dev/sda: TYPE="isw_raid_member"
/dev/sdb: TYPE="isw_raid_member"
/dev/mapper/isw_cehbidjbfj_RaidME1: UUID="94545494-9957-4533-b450-cb6c7e03535d" TYPE="swap"
/dev/mapper/isw_cehbidjbfj_RaidME2: UUID="aacdedd7-e423-4004-a8bf-2725d876b74e" TYPE="ext4"
/dev/mapper/isw_cehbidjbfj_RaidME3: UUID="0048EC0748EBF974" LABEL="Windows" TYPE="ntfs"
/dev/mapper/isw_cehbidjbfj_RaidME5: UUID="7e900ff0-f309-4c4e-90b4-281dd9024003" TYPE="ext4"
/dev/mapper/isw_cehbidjbfj_RaidME6: UUID="90284AB8284A9D5A" LABEL="Apps" TYPE="ntfs"
/dev/mapper/isw_cehbidjbfj_RaidME7: UUID="887C5C4C7C5C36E2" LABEL="Games" TYPE="ntfs"
/dev/mapper/isw_cehbidjbfj_RaidME8: UUID="50B46C57B46C4218" LABEL="Downloads" TYPE="ntfs"
/dev/sdc1: UUID="F26C710D6C70CDBB" LABEL="BookIT" TYPE="ntfs"

I guess if you can confirm that you will always have sdX or hdX then probably simple enough to manipulate
the string:

Should be able to map a = 1, b = 2, ...

So sda1 ... a = 1 and 1 - 1 = 0 therefore: hd1,0

webhope 04-28-2010 05:01 AM

Quote:

Originally Posted by grail (Post 3950333)

Code:

grail@wetworks:~$ sudo blkid
[sudo] password for grail:
/dev/sda: TYPE="isw_raid_member"
/dev/sdb: TYPE="isw_raid_member"
/dev/mapper/isw_cehbidjbfj_RaidME1: UUID="94545494-9957-4533-b450-cb6c7e03535d" TYPE="swap"
/dev/mapper/isw_cehbidjbfj_RaidME2: UUID="aacdedd7-e423-4004-a8bf-2725d876b74e" TYPE="ext4"
/dev/mapper/isw_cehbidjbfj_RaidME3:


I am confused from your blkid list :-(
For the 2nd uuid of your list on 1st column it returns:
/dev/mapper/isw_cehbidjbfj_RaidME2
So how this corresponds with your menu.lst if is this a system device?
I ask about your menu.lst root=??? argument

grail 04-28-2010 05:27 AM

My menu.lst:
Code:

title                Ubuntu 9.10, kernel 2.6.31-21-generic
root                (hd0,1)
kernel                /boot/vmlinuz-2.6.31-21-generic root=/dev/mapper/isw_cehbidjbfj_RaidME2 ro quiet splash
initrd                /boot/initrd.img-2.6.31-21-generic

Ubuntu did this by default.

webhope 04-28-2010 11:55 AM

Grail,
I also have Ubuntu (9.04) and I have there default root=UUID=<uuid>

We would just take your $1 column and giveit to root=<$1> place

webhope 04-28-2010 02:59 PM

So what's the problem. Why this command doesn't get the separated uuid (one item)

Code:

for d in ${uuid[@]}; do
echo $d
done

How to separate it to proceed $uuid as
1. $d=>eab515e9-bc3e-4024-9f01-55fddaa0fb1c
2. $d=>e12487ff-6d6f-44c4-9e03-33f545b3b798
in the loop?

grail 04-28-2010 07:15 PM

You have echoed the wrong item .... change:
Code:

echo $uuid

to

echo $d

Now you will have your items.

I was just thinking (sometimes this can be bad lol) you are going to a lot of trouble to alter an already unique identifier.
Just wondering if this is the best course of action??

webhope 04-29-2010 12:59 AM

Sometimes it's good to use uuid, sometimes it's better to use hd(?,?)

Quote:

Originally Posted by grail (Post 3951213)
change:
Code:

echo $uuid

to

echo $d

Now you will have your items.

I did mistake, but this is the same.

Code:

for d in ${uuid[@]}; do; clear; echo $d; read; done
Shows still 2 uuids instead the 1st, after Enter the 2nd.

grail 04-29-2010 01:43 AM

Now just to be sure, as i recently got caught out by someone else, you are using bash?
ie your code starts with:
Code:

#!/bin/bash
and not
Code:

#!/bin/sh
This has caused unusual problems for me before.

I have run the code below and am greeted with each line and waiting for enter key:
Code:

#!/bin/bash

uuid="title Sata Mandriva
kernel (hd0,2)/boot/vmlinuz BOOT_IMAGE=linux root=UUID=eab515e9-bc3e-4024-9f01-55fddaa0fb1c  resume=UUID=e12487ff-6d6f-44c4-9e03-33f545b3b798 splash=silent vga=788
initrd (hd0,2)/boot/initrd.img"

uuid=($(echo "$uuid" | awk 'BEGIN{RS="UUID="}/-/{gsub(/ .*/,"");print}'))

for x in ${uuid[@]}
do
        echo "|$x|"
        read
done


webhope 04-29-2010 02:23 AM

Problem found with IFS. The block precluding

Code:

OLD_IFS=$IFS; IFS="|";
content=($(awk 'BEGIN{RS=""; ORS="|"}/^title/' /boot/grub/menu.lst))
i=-1;
for block in ${content[@]}; do; block= block_new ; ... done;

Edit
This is the block from my last thread.
I just wonder why there is not IFS=$"|"; And why I don't see "|" on output when I run echo $IFS. It shows " "

grail 04-29-2010 03:00 AM

By default IFS is whitespace. If you run the following you will see what it is set to:
Code:

$>set | grep IFS
IFS=$' \t\n'

This is the output on my test machine. It behaves like an or for each item. So by default my machine would split on
a space or a tab or a new line.

Therefore doing echo $IFS will only show you an empty line.

Quote:

Problem found with IFS
Cannot see why this would be the case??
I presume you are doing a for within a for loop, the first would split content so block = stanza.
awk would then work on block and return a new array .... ahhh there it is ... took me a little bit,
because the new array has zero pipes in it it says that all data, ie both uuid's and new lines are one field.

Tricky :)

Maybe you need to rethink exactly what it is you want to change in menu.lst, ie is it necessary to break up each stanza
or maybe make your necessary replacements in place???

A really nasty hack would be to alter the IFS backward and forward in the loop, but I see this as potentially very messy and
may just run into more trouble if you expand further.

Just one extra word ... and i know this isn't really your fault per se, but if you are going to test something, like the code we have been
working on in this thread, you should first test in isolation and then add into your script, then we would have come across this issue
as putting it together with older script and not bashing our heads on whether or not it is doing the right thing, which it was.
Just a thought :)

webhope 04-29-2010 03:54 AM

OK so, now this works:

Code:

    IFS=$OLD_IFS; # In outer loop should be IFS="|";
    uuid=$( echo $block_new |  awk '/.*UUID=/{ x=gensub(/.*UUID=([^ ]+).*/,"\\1","g");  print x}')
    # TATO VARIANTA ZACHOVÁ JEN PRVNÍ VÝSKYT UUID. (simplest way to get the first uuid to be 2 simple subs)
    #          uuid=$( echo "$block_new" | awk '/UUID/{sub(/.*root=UUID=/,"");sub(/ .*/,"");print}')
    clear
    uuid=($(echo "$block_new" | awk 'BEGIN{RS="UUID="}/-/{gsub(/ .*/,"");print}'))
    for d in ${uuid[@]}; do
      dev=$(blkid | grep $d |  awk 'BEGIN{FS=":"} {print $1}');
      if [[ ! -z $dev  ]]; then
      echo $dev
      else
      echo "uuid $d  nenalezeno v seznamu zarizeni"
      fi;
    done

Now I try to prepare the hd(?,?) string. I have some code but I don't know how to define and when should be hd0 and when hd1. Is there always hd0 | hd1 or hd0 | hd1 | hd2 | hd3 according to sda/hda | sdb/hdb | sdc/hdc | sdd/hdd ? What posibilities we have?

hd(x,y)
Code:

hd=$(echo $dev |  awk 'BEGIN{RS="/dev/";} {
x=gensub(/^.*[sh]d(.)[[:digit:]]/,"\\1","g")
y=gensub(/^.*[sh]d.([[:digit:]])/,"\\1","g")
print x
}');


grail 04-29-2010 07:59 AM

I just had a thought and would like to back up a little :)

We seem to have missed the point that in any single menu.lst file there would only ever be a handful of UUIDs.
Meaning, root (/) will be assigned a UUID and the same for any other systems on the single machine, but, the UUID for root
would always be the same (as it is unique and only assigned to one value) and therefore you could now parse the entire file
for that UUID and change it and so on for the other UUIDs.

I thought it worth mentioning as, for example, the menu.lst you sent me had 20+ stanzas, but ultimately everywhere that root
is being referred to will have the same UUID.

So if the only reason to break the menu.lst into stanzas and then get the UUIDs to then be changed into hdx,y - I think this may be able to be done easier.

Let me know what you think or if you don't understand, ask me and I will see if I can draft a suggestion.

As for your recent post:
Quote:

Is there always hd0 | hd1 or hd0 | hd1 | hd2 | hd3 according to sda/hda | sdb/hdb | sdc/hdc | sdd/hdd ?
In a "normal" computer I would imagine it unlikely to have more than say 3 or 4 drives, but ultimately I am guessing there is no finite limit
if you could get your computer to have enough connections for a hundred drives I guess it is possible.


All times are GMT -5. The time now is 09:14 AM.