nosaj wrote:
[...] I am just looking for ideas as to how to go about it. I would prefer to NOT use awk.
I get this format in my tempfile:
/home/user1/filewithblue:The sky is blue.
/home/user2/filewithred: The car is red.
/home/user3/filewithgreen: The grass is green.
But I want this format to output to the screen:
user1 - The sky is blue. - /home/user1/filewithblue
user2 - The car is red. - /home/user2/filewithred
user3 - The grass is green. - /home/user3/filewithgreen
Use a
while/read loop to retrieve the two main fields (path and string found), delimited by a
colon, in different variables ( e.g., «
path » and «
srch » ), and some parameter expansions
to extract the username from the path, for each line read from the temporary file. The process
consists of removing the filename which is in the path, then store the result to remove what's in
front of the username, from the modification, to get solely the string that represents the name of
the user. Note that if your
grep(1) search was recursive, it'll fail and you'll get either a filename or
a directory name, instead of the username, so let's have another approach that will work: remove
the string «
/home/ » from the path, then remove what's to its right.
Now that you have every information needed stored in multiple variables, display them in your
desired format simply by expanding them and adding hyphens wherever you want them to be.
Code:
while IFS=' :' read -r path srch _; do
tmp=${path#*/*/}
printf '%s - %s - %s\n' "${tmp%%/*}" "$srch" "$path"
done < tempfile
________
nosaj wrote:
I only use one example per user but there will be multiple lines for each. I am also
wondering what command I would use to put an empty line (or two) in between
the different users to keep them separate.
[2] nosaj wrote:
I would prefer to NOT use awk.
It becomes tricky without
awk(1), and the solution won't fit with this forum's part ( i.e., « General suggestions and the
VERY basics » ).
I'll try to explain how I approached this problem by detailing the following code line per line, though.
Here is the code :
Code:
declare -A users
while IFS=' :' read -r path srch; do
tmp=${path#*/*/} u_name=${tmp%%/*}
printf -v sp '%*s' $((${#u_name} + 3))
if ((! ${#users["$u_name"]})); then
unset 'sp'
fi
users["$u_name"]+="$sp$srch - $path"$'\n'
done < tempfile
for u in "${!users[@]}"; do
printf '%s - %s\n' "$u" "${users[$u]}"
done
- Declare the variable called users as an associative array.
It'll be used to store each path and string according to one username ;
-
- - Retrieve the path and string found from each tempfile's line in
the variables path and srch respectively ;
- - Extract the part of the path corresponding to the username thanks to
two parameter expansions. The variable tmp will contain the path
minus the string « /home/ », and the variable u_name will contain
the username ;
- - Assign spaces to the variable called sp. The number of spaces is
determined by the size of the username retrieved, to which we add 3
(because there are three characters in between the username's last
character and the string's first one), to align the different informations
next to the username's right side, instead of displaying them below it ;
- - Test whether the part corresponding to the username found on the line,
stored in the array users, is empty, so that its size is 0 ;
- - If it is actually empty, then we unset the variable sp which contains the
spaces to make the alignment, because it means that there is no other
information before the one being read, so there is nothing to format ;
- - ( End of the test ; )
- - Append the fields which are meant to be after the username, with
the desired format, to the space dedicated for the actual username
in the array users. Each new pair of fields is separated by a newline
and padded with spaces stored in the variable sp to make the alignment ;
- - ( Redirect stdin ( file descriptor 0 ) to read input from the file called tempfile ; )
-
- - Loop through every index ( usernames ) of the array users ;
- Display the username, followed by the elements associated with it ;
- ( End of the loop. )