Bash Script - get User Name given UID - bash

How - given USER ID as parameter, find out what is his name? The problem is to write a Bash script, and somehow use etc/passwd file.

The uid is the 3rd field in /etc/passwd, based on that, you can use:
awk -v val=$1 -F ":" '$3==val{print $1}' /etc/passwd
4 ways to achieve what you need:
http://www.digitalinternals.com/unix/linux-get-username-from-uid/475/

Try this:
grep ":$1:" /etc/passwd | cut -f 1 -d ":"
This greps for the UID within /etc/passwd.
Alternatively you can use the getent command:
getent passwd "$1" | cut -f 1 -d ":"
It then does a cut and takes the first field, delimited by a colon. This first field is the username.
You might find the SS64 pages for cut and grep useful:
http://ss64.com/bash/grep.html
http://ss64.com/bash/cut.html

Related

How to grep only the first string in a line

I'm writing a script that checks a list of all the users connected to the server (using who) and writes to the file Information the list of usernames of only those having letters a, b, c or d. This is what I have so far:
who | grep '[a-d]' >> Information
However, the command who displays this:
username pts/148 2019-01-29 16:09 (IP address)
What I don't understand is why my grep search is also displaying the pts/148, date, time, and IP address. I just want it to send the username to the file Information.
Any help is appreciated.
Another way is to use the command cut to get the first part of the string only.
who | cut -f 1 -d ' ' | grep '[a-d]' >> Information
Using awk to output records where the first clumn matches [a-d]:
$ who | awk '$1~/[a-d]/' >> Information
Using grep to search for lines with [a-d] before the first space:
$ who | grep -o "^[^ ]*[a-d][^ ]*" >> Information
You need to get the first word, otherwise grep will display the entire line that has the matching text. You could use awk:
who | awk '{ if (substr($1,1,1) ~ /^[a-d]/ ) print $1 }' >>Information

Substring in linux using cut

I would like to grab a substring of a file to get the default password of mysql in centos.
This is the command I am using to get the password:
sudo grep 'temporary password' /var/log/mysqld.log
which result is:
2018-02-21T07:03:11.681201Z 1 [Note] A temporary password is generated for root#localhost: >KkHAt=#z6OV
Now, I am using this command to get the password only and remove the unnecessary stuff, so I can use it in a script:
sudo grep 'temporary password' /var/log/mysqld.log | cut -d ':' -f 4 | cut -d ' ' -f 2
But using 2 cuts seems very ugly. Is there another command or tool that I can use, or a more elegant way to do this?
Using awk:
$ awk '/temporary password/{print $NF}' file
>KkHAt=#z6OV
Bearing in mind that awk splits the lines in fields based on a field separator (by default whitspaces) and NF refers to the number of fields, you can print the last field with:
$ grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}'

How to compare a file to a list in linux with one line code?

Hey so got another predicament that I am stuck in. I wanted to see approximately how many Indian people are using the stampede computer. So I set up an indian txt file in vim that has about 50 of the most common surnames in india and I want to compare those names in the file to the user name list.
So far this is the code I have
getent passwd | cut -f 5 -d: | cut -f -d' '
getent passwd gets the userid list which is going to look like this
tg827313:x:827313:8144474:Brandon Williams
the cut functions will get just the last name so the output of the example will be
Williams
Now can use the grep function to compare files but how do I use it to compare the getent passwd list with the file?
To count how many of the last names of computer users appear in the file namefile, use:
getent passwd | cut -f 5 -d: | cut -f -d' ' | grep -wFf namefile | wc -l
How it works
getent passwd | cut -f 5 -d: | cut -f -d' '
This is your code which I will assume works as intended for you.
grep -wFf namefile
This selects names that match a line in namefile. The -F option tells grep not to use regular expressions for the names. The names are assumed to be fixed strings. The option -f tells grep to read the strings from file. -w tells grep to match whole words only.
wc -l
This returns a count of the lines in the output.

How to echo a string after sorting it by maximum length

so I am just learning bash and right now I am trying to write one line codes to solve some problems. So write now I am listing all the users in stampede and trying to get the length and name of the longest string.
So this is where I am at
getent passwd | cut -f 1 -d: | wc -L
getent passwd - (too get the userid list), the cut command to get the first userid and then wc -L to get the longest length. Now I am trying to figure out how do I echo that? So any input on that would be awesome thank you!
To get the name of the user with the longest name, use:
getent passwd | awk -F: '{longest=length($1)>length(longest)?$1:longest} END{print longest}'
How it works
-F:
Tell awk to use a colon as the field separator.
longest=length($1)>length(longest)?$1:longest
For every line of input, this statement is executed. It assigns to the variable longest the result of a ternary statement:
length($1)>length(longest)?$1:longest
This statement tests the condition length($1)>length(longest). Here, length($1) is the length of the name of the current user and length(longest) is the length of the longest name seen previously. If the current name is longer, the ternary expression returns the current name, $1. Otherwise, it returns the previous longest name, longest.
END{print longest}
After we have finished reading the file, this prints the name that was the longest.
One way to do this, that doesn't stray too far from what you have, is to use sed to only output lines that are at least as long as the length you get from your command above:
getent passwd | cut -f 1 -d: | sed -n /^.\\{`getent passwd | cut -f 1 -d: | wc -L`\\}/p
This will output all users which tie for the longest length.
You can make it a little nicer by storing the list of names in a variable:
u=`getent passwd | cut -f 1 -d:`; sed -n /^.\\{`wc -L <<< "$u"`\\}/p <<< "$u"
Another way of doing it:
getent passwd | cut -f 1 -d: | perl -ne 'print length($_).":$_"'| sort -n| cut -f 2 -d:
We create a list <length>:<username> with perl, sort by length and print only username.

awk for different delimiters piped from xargs command

I run an xargs command invoking bash shell with multiple commands. I am unable to figure out how to print two columns with different delimiters.
The command is ran is below
cd /etc/yp
cat "$userlist" | xargs -I {} bash -c "echo -e 'For user {} \n'
grep -w {} auto_*home|sed 's/:/ /' | awk '{print \$1'\t'\$NF}'
grep -w {} passwd group netgroup |cut -f1 -d ':'|sort|uniq;echo -e '\n'"
the output I get is
For user xyz
auto_homeabc.jkl.com:/rtw2kop/xyz
group
netgroup
passwd
I need a tab after the auto_home(since it is a filename) like in
auto_home abc.jkl.com:/rtw2kop/xyz
The entry from auto_home file is below
xyz -rw,intr,hard,rsize=32768,wsize=32768 abc.jkl.com:/rtw2kop/xyz
How do I awk for the first field(auto_home) and the last field abc.jkl.com:/rtw2kop/xyz? As I have put a pipe from grep command to awk.'\t' isnt working in the above awk command.
If I understand what you are attempting correctly, then I suggest this approach:
while read user; do
echo "For user $user"
awk -v user="$user" '$1 == user { print FILENAME "\t" $NF }' auto_home
awk -F: -v user="$user" '$1 == user { print FILENAME; exit }' passwd group netgroup | sort -u
done < "$userlist"
The basic trick is the read loop, which will read a line into the variable $user from the file named in $userlist; after that, it's all straightforward awk.
I took the liberty of changing the selection criteria slightly; it looked as though you wanted to select for usernames, not strings anywhere in the line. This way, only lines will be selected in which the first token is equal to the currently inspected user, and lines in which other tokens are equal to the username but not the first are discarded. I believe this to be what you want; if it is not, please comment and we can work it out.
In the 1st awk command, double-escape the \t to \\t. (You may also need to double-escape the \n.)

Resources