[SOLVED] Extracting another user's name in a file:/// entry

About writing shell scripts and making the most of your shell
Forum rules
Before you post please read how to get help
Post Reply
LittleScriptMan
Level 1
Level 1
Posts: 20
Joined: Thu Jan 13, 2022 8:42 am

[SOLVED] Extracting another user's name in a file:/// entry

Post by LittleScriptMan »

I'll give some ground to my request with an example. My favorites list on my desktop looks like this :

Code: Select all

['file:///home/desk_name/Documents/Perso/Media/DOCUS%201080.txt::text/plain', 'file:///home/desk_name/System/Firefox/My_Prefs.js::application/javascript']
and some others I'll pass.

My laptop has the same user structure (same names, files locations ...) just the username changes (let's say lap_name).

If I redirect these favorites to a file and manually use xed's search & replace function to replace desk_name with lap_name everything works fine and my favorites are set accordingly on my laptop.

I'm trying to script this but am currently not smart enough to extract desk_name when I'm on my laptop. On the desktop, it's easy because it's $USER.

The question could also be rephrased as :
How to extract a username from an absolute path created by an account where username is not the $USER ?
if it's easier to tackle the problem this way.

Thanks for any help or advice.
Last edited by LittleScriptMan on Sun Jan 16, 2022 4:12 am, edited 1 time in total.
rene
Level 19
Level 19
Posts: 9233
Joined: Sun Mar 27, 2016 6:58 pm

Re: Extracting another user's name in a file:/// entry

Post by rene »

The query makes not enormous sense to me. Is there anything wrong with, for the correct values of "desk_name", "lap_name" and whatever list you speak of, a simple e.g. sed?

Code: Select all

sed -i s/desk_name/lap_name/g /where/ever/favorites.list
LittleScriptMan
Level 1
Level 1
Posts: 20
Joined: Thu Jan 13, 2022 8:42 am

Re: Extracting another user's name in a file:/// entry

Post by LittleScriptMan »

rene wrote:
Fri Jan 14, 2022 5:29 am
The query makes not enormous sense to me. Is there anything wrong with, for the correct values of "desk_name", "lap_name" and whatever list you speak of, a simple e.g. sed?
No, it won't.
The problem is : when you don't want to bother people with your project, you end giving them insufficient infos to really understand what's going on. So' I'll try to be more precise :
I wrote quite a number of functions performing the elementary tasks to get some custom infos of my system. I won't give the whole list but names will speak for them : GetNemoConf, GetFavs, GetMenuItems, GetCustIcons...
These functions all write their data into an associated .cust file (nemo.cust, favs.cust, menu.cust, icon.cust...)
Of course there is a "Set" function associated to be able to recover these datas (SetNemoConf, SetFavs...)
In most of these .cust files there are items / lines with the file:/// header I mentioned in my original post followed by an absolute path.

Restoring on the same computer works fine because absolute paths are identical to the .cust files. The idea is to be able to transfer these config files on another computer (of course, must have the same distro and DE settings) and to replace every occurrence of the previous user (desk_user) with the new one (lap_user) in all files. However, if some nice settings are made on the laptop, the reverse is also meant to be possible (transfering the .cust files from the laptop to the desktop and some other computers I didn't mention)
This can already be done by the function :

Code: Select all

TranslateUserName() {
	local PrevUser=$1
	find $CustDir -name '*.cust' -exec sed -i 's|home/'$PrevUser'|home/'$USER'|g' {} +
}
$CustDir is a global variable defined in .bashrc containing the directory where all those .cust files and some others are saved - It has neither spaces nor fancy extension but I'll remember about the double quotes for portability :wink: . $PrevUser has no sense under that form - $1 would do the job as well.

As you've noticed TranslateUserName() needs an argument, the previous user. What I'm looking for is automation of the process without any argument and just getting the previous user (which is not always the same) by extracting his name from any file:/// output and put it in the $PrevUser variable, something like
PrevUser=$(GetPrevUserNameFromFile///)
(that is by no means a syntax)

Feel free to ask if I wasn't clear enough
rene
Level 19
Level 19
Posts: 9233
Joined: Sun Mar 27, 2016 6:58 pm

Re: Extracting another user's name in a file:/// entry

Post by rene »

In that case it seems you just want to replace any occurrence of file:///home/*/ with file:///home/$USER/. You can easily do that without need for extracting PrevUser with e.g.

Code: Select all

sed -i "s,/home/[^/]\+/,/home/$USER/,g" "$CustDir"/favs.cust
Using s,,,g rather than your s|||g only as a (strong) personal preference. There's moreover no need for the find | exec:

Code: Select all

sed -i "s,/home/[^/]\+/,/home/$USER/,g" "$CustDir"/*.cust
Finally I'd probably match a bit more strict on the file:// part as well with

Code: Select all

sed -i "s,file:///home/[^/]\+/,file:///home/$USER/,g" "$CustDir"/*.cust
which would then be all of your TranslateuserName() function.

If you're set on in fact extracting PrevUser you could use e.g.

Code: Select all

PrevUser=$(sed "\,.*file:///home/\([^/]\+\)/.*,s,,\1,;q" "$CustDir"/favs.cust)
User avatar
Termy
Level 8
Level 8
Posts: 2025
Joined: Mon Sep 04, 2017 8:49 pm
Location: UK
Contact:

Re: Extracting another user's name in a file:/// entry

Post by Termy »

LittleScriptMan wrote:
Fri Jan 14, 2022 8:29 am
...
It sounds like you just need the user's name, which you can do super easily by accessing the special $USER environment variable. You're already using that variable though, so I'll assume I'm missing something. Instead of using /home/$USER, you might find it better to just use $HOME. Remember, both those environment variables refer to the current user.

If I just needed to replace existing text with a different user to one for the current user, I'd use something like:

Code: Select all

CurPath='/home/someuser/path/to/nowhere'
printf '%s\n' "$HOME/${CurPath#/*/*/}"
Or:

Code: Select all

CurPath='file:///home/someuser/path/to/nowhere'
printf '%s\n' "file://$HOME/${CurPath#file:///*/*/}"
Last edited by Termy on Fri Jan 14, 2022 2:14 pm, edited 3 times in total.
Confused? Here's a guide to this board!
Psst... I'm Terminalforlife on YouTube.
LittleScriptMan
Level 1
Level 1
Posts: 20
Joined: Thu Jan 13, 2022 8:42 am

Re: Extracting another user's name in a file:/// entry

Post by LittleScriptMan »

First of all, many thanks for your time and very valuable help. I'll work on it during the week-end and let you know if something worked as I want.
rene wrote:
Fri Jan 14, 2022 1:01 pm
In that case it seems you just want to replace any occurrence of file:///home/*/ with file:///home/$USER/.
To be precise replace any occurrence of /home/*/ with /home/$USER/ because some parameters begin with file://, some with directory:// (image-source='directory:///home/lap_user/Images'), some directly with /home/$USER ("download_location": "/home/lap_user/Downloads",).
rene wrote:
Fri Jan 14, 2022 1:01 pm
Using s,,,g rather than your s|||g only as a (strong) personal preference. There's moreover no need for the find | exec:
Just a remark about the find -> exec. It is not really useful now, I agree. The point was to be able to make subdirs if I end up overwhelmed :) by the custom files, like $CustDir\Cinnamon, $CustDir\Apps ... and allow the TranslateUserName function to perform recursively through those subdirs with the help of find. Perhaps there's another way of doing it.

For the time being, as my $CustDir is still "flat" (no subdir), I will try your tips as suggested and perhaps try to enhance after reporting to you what works as expected.

Meanwhile, many thanks again.
LittleScriptMan
Level 1
Level 1
Posts: 20
Joined: Thu Jan 13, 2022 8:42 am

Re: Extracting another user's name in a file:/// entry

Post by LittleScriptMan »

Termy wrote:
Fri Jan 14, 2022 2:06 pm
Remember, both those environment variables refer to the current user.
Yes and that's the problem. I'm not trying to access the current $USER which is quite easy, but a previous user. To make it simple let's say I'm sending you my favorites :

Code: Select all

['file:///home/LSM/Documents/Perso/Media/Docs.txt::text/plain', 'file:///home/LSM/System/Firefox/My_Prefs.js::application/javascript']
Even if you have the Docs.txt and My_Prefs.js in the same location than me, it won't work on your system because the absolute paths will probably begin with something like /home/Termy/. And the problem is that the string to replace is not $USER (which is Termy on your system), but a previous user called LSM (my initials to make it short :D ).

I'll try rene's suggestions and will come back. Thanks for showing interest to my problem.
LittleScriptMan
Level 1
Level 1
Posts: 20
Joined: Thu Jan 13, 2022 8:42 am

Re: Extracting another user's name in a file:/// entry

Post by LittleScriptMan »

Issue solved.
rene was almost immediately successful. Actually, successful is for him and almost for me because I hadn't noticed that, in all those custom files, one entry was based on the home path without the trailing slash. So a slight modification of suggestion 3 :
rene wrote:
Fri Jan 14, 2022 1:01 pm
sed -i "s,/home/[^/]\+/,/home/$USER/,g" "$CustDir"/*.cust
to

Code: Select all

sed -i "s,/home/[^/]\+,/home/$USER,g" "$CustDir"/*.cust
did the job

And pasting it into the original command of mine to become :

Code: Select all

find $CustDir -name '*.cust' -exec sed -i "s,/home/[^/]\+,/home/$USER,g" {} +
it even works recursively.

I will soon close the topic, but it would be unfair to do it before the hero of the day :wink: has an opportunity to give his opinion about the recursion of the command.
For the present, many thanks, rene. The day I'll master sed and other commands like you, I may improve to BigScriptMan :D .
Last edited by LittleScriptMan on Fri Jan 14, 2022 7:20 pm, edited 1 time in total.
rene
Level 19
Level 19
Posts: 9233
Joined: Sun Mar 27, 2016 6:58 pm

Re: Extracting another user's name in a file:/// entry

Post by rene »

Mmm, yes: that closing / was there on purpose (aiming to avoid an issue with greedy matching) but looking better that's not in fact necessary here so that'll be fine indeed. You can not however have single quotes around the sed expression since that disables expansion of $USER: I'd double-quote also "$CustDir" and "*.cust" but certainly then the "s,/home/[^/]\+,/home/$USER,g" needs to be.

Otherwise good that it helped.
rene
Level 19
Level 19
Posts: 9233
Joined: Sun Mar 27, 2016 6:58 pm

Re: Extracting another user's name in a file:/// entry

Post by rene »

Actually,

Code: Select all

$ echo ['file:///home/desk_name::text/plain'] | sed "s,/home/[^/]\+,/home/$USER,g"
[file:///home/rene/plain]
Not avoided with the closing / either but since you said that "one entry was based on the home path without the trailing slash" you may need to make doubly sure that in fact all's well now.
LittleScriptMan
Level 1
Level 1
Posts: 20
Joined: Thu Jan 13, 2022 8:42 am

Re: Extracting another user's name in a file:/// entry

Post by LittleScriptMan »

rene wrote:
Fri Jan 14, 2022 5:48 pm
Mmm, yes: that closing / was there on purpose (aiming to avoid an issue with greedy matching) but looking better that's not in fact necessary here so that'll be fine indeed. You can not however have single quotes around the sed expression since that disables expansion of $USER: I'd double-quote also "$CustDir" and "*.cust" but certainly then the "s,/home/[^/]\+,/home/$USER,g" needs to be.

Otherwise good that it helped.
Absolutely correct. I pasted the correct command in my script (with double-quotes).
And was a bit lazy to reopen all the script files and just pasted my first command in the function I posted above with single-quotes and updated with your command Nonsense, but the week is ending and the mind needs some rest.
So the script works with double-quotes and probably not (didn't even try) with single ones (a real case of miss-quoting :D ).

About the double-quotes for the dir/file variable, I'm taking it seriously in account. My behavior not to use them is of course back-grounded by the fact I don't use fancy names or spaces, but also by my script editor (geany). It's more logical to me that $CustDir has the same color than find, name... than "Hello" which would be the case of "$CustDir". However, I will now be looking for a colorscheme for geany where " " strings are displayed with a different color than "$ " strings to be able to comply with those more portable double-quote variables.

PS : I also found how to correct previous posts, so I corrected the command you pointed out.
Post Reply