How to remove all spaces from command output - bash

I'm writing a bash script for ssh key need to compare from local to remote. I have the command to check the key but command output result shows line by line. I need to get the output without spaces is there anyway to get output which is I'm expecting.

$ cat ex.txt
this is an example
this is line 2
$ cat ex.txt |tr -d ' '
thisisanexample
thisisline2
$ cat ex.txt |tr -d '\n'
this is an example this is line 2
$ cat ex.txt |tr -d '\n'' '
thisisanexamplethisisline2
tr = translate or delete characters
-d = delete character / characters
'\n' = newlines
' ' = spaces

Related

Bash - Searching in a file log

I have a bash script that saves a date (of last change), filename, maybe number of changes etc in a file (something similar to ls output).
Is there any way to search in this file in bash, eg. get the most used file or the most recent file, but just the filename?
So the file looks something like this:
2018-03-28 19:47:41 filename1
2018-03-28 19:49:24 filename2
2018-03-28 19:50:14 filename1
2018-03-28 19:50:17 filename3
Now I would like to get the file that was used last, so I shall sort it (it's actually sorted already), but I only want to get the filename of the file last edited (with the latest date). Is there a way to do this apart from regex?
If I understand you correctly:
head -1 foo.txt | tr -s ' ' | cut -d ' ' -f 3 # First line of foo.txt, only the filename
tail -1 foo.txt | tr -s ' ' | cut -d ' ' -f 3 # Last line
will give you the lines you want (thanks to this). If foo.txt is already sorted, those will be the earliest and latest.
To store those in variables:
firstfn="$(head -1 foo.txt | tr -s ' ' | cut -d ' ' -f 3)"
echo "First filename is $firstfn" # just a test
lastfn="$(tail -1 foo.txt | tr -s ' ' | cut -d ' ' -f 3)"
If you have awk, you can do this more simply (thanks to this answer):
awk -- 'END { print $3; }' foo.txt
for the last line, or
awk -- '{ print $3; exit }' foo.txt
for the first line. Same deal with the variables, e.g.,
firstfn="$(awk -- '{ print $3; exit }' foo.txt)"

Linux command echo files names until char

Here is my code
cd /bin/
echo *xyz?2* | cut -f 1 -d '.'
Please, how can i change this command to display files without extension ?
Bests.
Dump the filenames into an array and then use parameter expansion:
$ arr=(xyz?2*); echo "${arr[*]%.*}"
xyz32281 xyz32406 xyz32459 xyz3252 xyz7214 xyz8286
Assuming your filenames don't have any whitespace or glob characters.
You can just use printf '%s\n' instead of echo in your command:
printf '%s\n' *xyz?2* | cut -f 1 -d '.'
xyz32281
xyz32406
xyz32459
xyz3252
xyz7214
xyz8286
If you must use echo then use awk as this:
echo *xyz?2* | awk '{for(i=1; i<=NF; i++) print (split($i, a, /\./)==2 ? a[1] : $i)}'
xyz32281
xyz32406
xyz32459
xyz3252
xyz7214
xyz8286
This awk command iterated through each filename matched by glob pattern and splits each name by dot. If dot is found then first part is printed otherwise full filename is printed.
Your problem is that all files of echo *xyz?2* are shown in one line. When the filenames are without spaces/newlines, you can fix this by moving them to different lines and joining theem again when finished.
echo *xyz?2* | tr ' ' '\n' | cut -f 1 -d '.' | tr '\n' ' '| sed '$s/ $/\n/'
You can do this a lot easier with sed:
echo *xyz?2* | sed 's/[.][^. ]*//g'

Grep command not giving expected output

I am running the below line in a shell script
echo "$(tr -s '\n' ' ' < ${data[1]} | grep -oP '<af:popup.*?"${data[2]}".*?>')"
echo "(tr -s '\n' ' ' < ${data[1]} | grep -oP '<af:popup.*?"${data[2]}".*?>')"
The command is supposed to translate all \n from file ${data[1]} and inside this file a pattern something like this:
(af:popup.*?logicalCostingRecordExistsPopup.*?)
Issue is the first line is returning null data. Just to validate my script, I echoed the command to check what is getting replaced and run in directly in a shell.Output came as below
tr -s '\n' ' ' < hello.jsff | grep -oP '<af:popup.*? logicalCostingRecordExistsPopup.*?>'
When I run it directly in shell, it gives me expected output.
Don't know why it is not giving output when running inside in shell script
Instead of using double quotes, use single quotes.
echo "$(tr -s '\n' ' ' < ${data[1]} | grep -oP '<af:popup.*?'${data[2]}.*?>')"

How to display output on single line?

How would get a something like this for example in git when I do cat /.ssh/id_rsa.pub
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQCvS2bHikv4KsAAPfX6uRovwuZ3YPcx63DnykdBfEejw3/VaDooKVDRYaW6G7rjSub9iug82oD6Kk2n0Txk3CHpNjCDmoKyI1g7HgHjFMFl3q3qsejMhWtHVz176adlaqXRdYZaMnMXON54Khz2V/7Ghg2wMPG+e6NziGxJF3GvrTaiI/TtkehkZH4htkMy1Vr5mE1Vn5BpkacO7Ms8748xaTgfWVt4ssd8cDR5voxClKBVGJEeir5fLVC0HEJv9p6FFkPMV/qpffxGrvdZ4rUxuh/zhVznALsuhc0sSdDueCtcIcOqE2iwijrwi5uw3irdmfdsnkvsdfasd
Johnny#Johnny-PC
Into one line using the cat command that is suppose to print out text in the file in git like so:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvS2bHikv4KsAAPfX6uRovwuZ3YPcx63DnykdBfEejw3/VaDooKVDRYaW6G7rjSub9iug82oD6Kk2n0Txk3CHpNjCDmoKyI1g7HgHjFMFl3q3qsejMhWtHVz176adlaqXRdYZaMnMXON54Khz2V/7Ghg2wMPG+e6NziGxJF3GvrTaiI/TtkehkZH4htkMy1Vr5mE1Vn5BpkacO7Ms8748xaTgfWVt4ssd8cDR5voxClKBVGJEeir5fLVC0HEJv9p6FFkPMV/qpffxGrvdZ4rUxuh/zhVznALsuhc0383290jnfdsafdjasa Johnny#Johnny-PC
EDIT: I have tried using cat ~/.ssh/id_rsa.pub | awk '{print}' ORS=' ' but it still does the same thing.. I get this:
I have also tried using cat somefile | tr -d '\n' but unfortunetely it gives me the same results too:
This seems to be the simplest way. Tr just deletes the new line characters.
cat somefile | tr -d '\n'
You simply have to replace the new line with empty string
cat ~/.ssh/id_rsa.pub | awk '{print}' ORS=' '
This will print it on a single line
Demo
remove newlines and spaces from key's
cat id_rsa | tr '\n' ' ' | sed 's/ //g'

I want to re-arrange a file in an order in shell

I have a file test.txt like below spaces in between each record
service[1.1],parttion, service[1.2],parttion, service[1.3],parttion, service[2.1],parttion, service2[2.2],parttion,
Now I want to rearrange it as below into a output.txt
COMPOSITES=parttion/service/1.1,parttion/service/1.2,parttion/service/1.3,parttion/service/2.1,parttion/service/2.2
I've tried:
final_str=''
COMPOSITES=''
# Re-arranging the composites and preparing the composite property file
while read line; do
partition_val="$(echo $line | cut -d ',' -f 2)"
composite_temp1_val="$(echo $line | cut -d ',' -f 1)"
composite_val="$(echo $composite_temp1_val | cut -d '[' -f 1)"
version_temp1_val="$(echo $composite_temp1_val | cut -d '[' -f 2)"
version_val="$(echo $version_temp1_val | cut -d ']' -f 1)"
final_str="$partition_val/$composite_val/$version_val,"
COMPOSITES=$COMPOSITES$final_str
done <./temp/test.txt
We start with the file:
$ cat test.txt
service[1.1],parttion, service[1.2],parttion, service[1.3],parttion, service[2.1],parttion, service2[2.2],parttion,
We can rearrange that file as follows:
$ awk -F, -v RS=" " 'BEGIN{printf "COMPOSITES=";} {gsub(/[[]/, "/"); gsub(/[]]/, ""); if (NF>1) printf "%s%s/%s",NR==1?"":",",$2,$1;}' test.txt
COMPOSITES=parttion/service/1.1,parttion/service/1.2,parttion/service/1.3,parttion/service/2.1,parttion/service2/2.2
The same command split over multiple lines is:
awk -F, -v RS=" " '
BEGIN{
printf "COMPOSITES=";
}
{
gsub(/[[]/, "/")
gsub(/[]]/, "")
if (NF>1) printf "%s%s/%s",NR==1?"":",",$2,$1
}
' test.txt
Here's what I came up with.
awk -F '[],[]' -v RS=" " 'BEGIN{printf("COMPOSITES=")}/../{printf("%s/%s/%s,",$4,$1,$2);}' test.txt
Broken out for easier reading:
awk -F '[],[]' -v RS=" " '
BEGIN {
printf("COMPOSITES=");
}
/../ {
printf("%s/%s/%s,",$4,$1,$2);
}' test.txt
More detailed explanation of the script:
-F '[],[]' - use commas or square brackets as field separators
-v RS=" " - use just the space as a record separator
'BEGIN{printf("COMPOSITES=")} - starts your line
/../ - run the following code on any line that has at least two characters. This avoids the empty field at the end of a line terminating with a space.
printf("%s/%s/%s,",$4,$1,$2); - print the elements using a printf() format string that matches the output you specified.
As concise as this is, the format string does leave a trailing comma at the end of the line. If this is a problem, it can be avoided with a bit of extra code.
You could also do this in sed, if you like writing code in line noise.
sed -e 's:\([^[]*\).\([^]]*\).,\([^,]*\), :\3/\1/\2,:g;s/^/COMPOSITES=/;s/,$//' test.txt
Finally, if you want to avoid external tools like sed and awk, you can do this in bash alone:
a=($(<test.txt))
echo -n "COMPOSITES="
for i in "${a[#]}"; do
i="${i%,}"
t="${i%]*}"
printf "%s/%s/%s," "${i#*,}" "${i%[*}" "${t#*[}"
done
echo ""
This slurps the contents of test.txt into an array, which means your input data must be separated by whitespace, per your example. It then adds the prefix, then steps through the array, using Parameter Expansion to massage the data into the fields you need. The last line (echo "") is helpful for testing; you may want to eliminate it in practice.

Resources