Finding the part of a filename

Hi,

I am writing an ebuild for Gentoo Linux operating system.

Writing an ebuild is about Bash scripting where I am a newbie.

So, my ebuild must find a part of a specific filename.
Such a filaname my look like this:

libvclient_release_x64.so.740

and I must to find the number at the and of filename, which is in this case 740.

This number will change with time ( eg. it was a few days ago 734 ) so my ebuild must find it to works properly.

If I can to find this part of filename, then I can to store it into a variable which can then use further in the ebuild script.

The file path is known for my ebuild script but the filename can change, but only that number at the end of filename.

How can I find that part of the filename?

Best, P�l

specific_filename=libvclient_release_x64.so.740

number=${specific_filename##*[.]}

It works,

echo ${number}

gives

740

But what I want is the following.
How can I find the number - in this case the 740 - if I do not know the full specific_filename?
Eg. I know only the 'libvclient_release_x64.so.' part of the filename, but do not know the last '740' part of it, and want to find that unknown part?

specific_filename=libvclient_release_x64.so.*

does not do the job.

Hello csanyipal,

Welcome to forums, I hope you will enjoy learning and sharing knowledge here. Could you please try following and let me know if this helps you.

filename="libvclient_release_x64.so.740"
val=$(cut -d"." -f3 <<<$filename)
echo $val
740

EDIT: Adding this solution after seeing your POST#2, let me know if this helps you.

awk 'FNR==1{if(name){close(name)};split(FILENAME, a,".");print a[3];name=FILENAME;nextfile}' libvclient_release_x64.so.*
 

Thanks,
R. Singh

1 Like

It works, thank you.
I wonder if it works if the filname will change so, so the number at the and will change into four digit number too?

Hello csanyipal,

Glad that it helped you. You could HIT THANKS button at left most corner of each post if you find any post useful. Off course above will not work for every file name. Since you have provided pattern specific file patterns so I had written as per that file name(s). You may need to change the pattern of file(s) in case your name changes too.

Let me know if you have any queries on same.

Thanks,
R. Singh

1 Like

I am trying to use this in my ebuild:

lvcltno=awk 'FNR==1{if(name){close(name)};split(FILENAME, a,".");print a[3];name=FILENAME;nextfile}' \
           opt/VServer/vcomponents/libvclient_release_x64.so.*

dosym libvclient_release_x64.so."${lvcltno}" "${EPREFIX}/usr/$(get_libdir)/libvclient_release_x64.so"

but it does not work, the symlink is not created properly:

libvclient_release_x64.so -> libvclient_release_x64.so.

It seems that that the link is pointing to it self. Why? How can I fix this?

Hello csanyipal,

Not sure what you are trying to do, so please try my suggestion into a test environment only.
Also in awk we can't use variable values by using $ , by seeing your command I tried making following command(considering your command works on shell only).

awk -vLVCLINTO=${lvcltno} -veprefix=${EPREFIX} -vGET_LIBDIR=$(get_libdir) 'FNR==1{if(name){close(name)};split(FILENAME, a,".");;name=FILENAME;system("dosym libvclient_release_x64.so."LVCLINTO FS eprefix"/usr/"GET_LIBDIR"/libvclient_release_x64.so");nextfile}' /opt/VServer/vcomponents/libvclient_release_x64.so.*
 

Thanks,
R. Singh

Hello R.,

I am trying to add the output of your awk command to a variable, and later in my ebuild to use this variable. I search and find how to do it:

lvcltno="$(awk 'FNR==1{if(name){close(name)};split(FILENAME, a,".");print a[3];name=FILENAME;nextfile}' opt/VServer/vcomponents/libvclient_release_x64.so.*)"
dosym libvclient_release_x64.so."${lvcltno}" "${EPREFIX}/usr/$(get_libdir)/libvclient_release_x64.so"

Now my ebuild creates symlinks properly.
Best, P�l

There is some essential info missing in your specification:

  • Is it always the same (root or base, without sequence No.) file name? If not, how is the (partial) file name supplied?
  • Is there always one single version only or can there be multiple ? If so, which version do you want?
  • Why does specific_filename=libvclient_release_x64.so.* "not do the job"?What's the error?

It is always the same file name, without the trailing number which changes only.
I do not understand your second question. Version of what?

Do e.g.

libvclient_release_x64.so.734
libvclient_release_x64.so.740

exist at the same time?

No, it does not. There will be only one version of that file out there.

---------- Post updated at 10:13 PM ---------- Previous update was at 10:05 PM ----------

The answer for the third question follows.

specific_filename=libvclient_release_x64.so.*
number=${specific_filename##*[.]}
echo $number

The output of third command is:

libicudata.so 
libicudata.so.54 
libicui18n.so 
libicui18n.so.54 
libicuio.so 
libicuio.so.54 
libicuuc.so 
libicuuc.so.54 
libvclient_release_x64.so 
libvclient_release_x64.so.740 
libvkernel_release_x64.so 
libvkernel_release_x64.so.740 
libvreport_release_x64.so 
libvreport_release_x64.so.740 
libvshared_release_x64.so 
libvshared_release_x64.so.740

and not the number 740.

That is difficult to understand or believe, respectively. I touch ed all those files:

ls -la lib*
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicudata.so
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicudata.so.54
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicui18n.so
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicui18n.so.54
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicuio.so
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicuio.so.54
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicuuc.so
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libicuuc.so.54
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvclient_release_x64.so
-rw-rw-r-- 1 user user    0 Aug 21 20:36 libvclient_release_x64.so.734
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvclient_release_x64.so.740
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvkernel_release_x64.so
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvkernel_release_x64.so.740
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvreport_release_x64.so
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvreport_release_x64.so.740
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvshared_release_x64.so
-rw-rw-r-- 1 user user    0 Aug 21 22:26 libvshared_release_x64.so.740

and there will be just two files found for the pattern you gave:

echo libvclient_release_x64.so.*
libvclient_release_x64.so.734 libvclient_release_x64.so.740

There should NOT be that multitude of files listed that you present as the output of echo $number . What be the output of echo libvclient_release_x64.so.* in that environment?

Sorry, I can't follow you. Where did you run the

ls -la lib*

command?

In a test directory on my host, where I created all the files you showed with the touch command.
Again: the error you posted is not reproducible without further information. The reason I insist is that the proposal in post#2 is the most cost / resource effective one and should work perfectly.

Hello RudiC,

you can download the Valentina Server Linux 64 DEB deb package from here: Download
then unpack it with

ar x vserver_x64_7_lin.deb

Then you get three files:
control.tar.gz
data.tar.xz
debian-binary

Further, you can unpack the data.tar.xz archive and get three directories:
etc/
opt/
usr/

In the opt/VServer/ dir there is among others the
vcomponents/ dir, which contains the files which are in question.

You can see there that in vcomponents/ dir is only one version of libraries, currently it is 740 version. So at a time there is only one number at the end of some filenames.

When my ebuild on Gentoo Linux system unpack the downloaded deb package, it gets the exact dirs and files out there. Naturally, the files and it's versions will change at time.

I hope I explained to you what is the situation. Right?

Best, P�l

If it is made very sure that there will be only one numbered file version at a time, then why do you need to find out the sequence number? Create the symlink immediately to the only version that exists.
I presume the dosym command does exactly this: create a symbolic link. If not so, what does it do?

1 Like

I think i can clear up the confusion:

What rdtx1 gave you is a so-called variable expansion in the shell.

This:

Respectively the last part: ${variable_name##*[.]} means: take from the content of variable_name everything after the last ".". To understand how it works try this:

# string="bla.foo.before-dot.after-dot"
# echo ${string##*[.]}
after-dot

So, rdtx1 showed you a way of isolating the part you are interested in from the full filename. You will still have to provide the full filename first.

But you tried to use an asterisk "*" as part of the filename. This is expanded by the shell not to a single filename but a list of names. Consider the following:

# ls -l
total 0
-rw-rw-r-- 1 bakunin users 0 Aug 22 15:04 afile.123
-rw-rw-r-- 1 bakunin users 0 Aug 22 15:04 bfile.456
-rw-rw-r-- 1 bakunin users 0 Aug 22 15:04 cfile.789

# var=afile.123          # storing a fixed name in the variable
# echo ${var##*[.]}
123

# var=*                    # storing the asterisk
# echo $var
afile.123 bfile.456 cfile.789

# echo ${var##*[.]}

The reason for this is that in fact the content of the variable is "" and you can't remove any "part before the dot" because there isn't any dot. But when you try to display this asterisk with the echo -command the shell replaces it with a list of files named along the pattern (i.e. when you specifiy "abc" the pattern is "all files with names starting with "abc").

Therefor you need to not use the asterisk as part of your variables content but the list it produces - and then trim the resulting filenames one at a time with the expression rdtx1 gave you. Like this:

ls | while read filename ; do
     echo "filename is: $filename trimmed filename is: ${filename##*[.]}"
done

I hope this helps.

bakunin

1 Like