How to display output on single line? - shell

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'

Related

Count how many words in file test.txt start with “tol”?

I'm new to Linux shell. I know there are tools to do this thing, such as awk. But I'm wondering if I could do it using grep or wc or other commands? awk seems intimidating to me. Thanks.
I tried grep and wc, like this:
grep tol test.txt | wc -w
But grep will give me the whole line.
If I tried the following:
grep '^tol$*' test.txt | wc -w
It only counts the line begins with mol.
How can I grep the words starting with tol?
Something like that:
grep -o '\<tol[[:alpha:]]*\>' test.txt | wc -w
< - for beginning of the word,
> - the end of the word.
[[:alpha:]] - to avoid match of combinations like tol123 (You said you need only words).
-o - to show only matches, not the entire line.
You can do the same fairly simply with awk, e.g.
awk '{for(i=1;i<=NF;i++) $i~/^tol/ && n++} END {print n}'
Example
$ echo -e "tolerance topaz tolstoy\nbats toluene toledo" |
> awk '{for(i=1;i<=NF;i++) $i~/^tol/ && n++} END {print n}'
4
Another option is to translate all whitespace characters into linefeeds so that each word starts on a new line, then grep can count them itself:
echo -e "tolerance topaz\ttolstoy\nbats toluene toledo" | tr '[:space:]' '\n' | grep -c "^tol"
4
Or, if using a file called words.txt:
tr '[:space:]' '\n' < words.txt | grep -c "^tol"

Add symbol every 2 bytes

I have a string 20000024ff3dbf50 that I would like to convert it like: 20:00:00:24:ff:3d:bf:50, I've tried with sed:
echo 20000024ff3dbf50 | sed 's/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1:\2:\3:\4:\5:\6:\7:\8/'
but it's a little ugly.
Two substitutions:
echo "20000024ff3dbf50" | sed 's/../&:/g;s/.$//'
Results:
20:00:00:24:ff:3d:bf:50
echo 20000024ff3dbf50 | grep -o .. | paste -d ':' -s -
Grep with -o splits the input to 2 chars per line;
paste uses delimiter ':' to pad them [-s]erially
You could also use GNU awk auto-splitting for this:
echo 20000024ff3dbf50 | awk '$1=$1' FPAT=.. OFS=:
Output:
20:00:00:24:ff:3d:bf:50

Bash how to append word to end of a line?

I have executed a command in bash to retrieve some addresses from a file like this:
grep address file.txt | cut -d'=' -f2 | tr ':' ' '
yields:
xxx.xx.xx.xxx port1
xxx.xx.xx.xxx port2
and I would like to append ' eth0' to each of those output lines and then ideally for loop over the result to call a command with each line. Problem I'm having is getting that extra string in the end to each line. I tried:
| sed -e 's/\(.+)\n/\1 eth0/g'
which didn't work..and then supposing I got it there, if I wrap it in a for loop it won't pass in the full lines since they contain spaces. So how do I go about this?
You can match $ to append to a line, like:
sed -e 's/$/ eth0/'
EDIT:
To loop over the lines, I'd suggest using a while loop, like:
while read line
do
# Do your thing with $line
done < <(grep address file.txt | cut -d'=' -f2 | tr ':' ' ' | sed -e 's/$/ eth0')
How about just using awk:
awk -F= '/address/{gsub(/:/," ");print $2,"eth0"}' file
Demo:
$ cat file
junk line
address=192.168.0.12:80
address=127.0.0.1:25
don not match this line
$ awk -F= '/address/{gsub(/:/," ");print $2,"eth0"}' file
192.168.0.12 80 eth0
127.0.0.1 25 eth0
Or just with sed:
$ sed -n '/address/{s/:/ /g;s/.*=//;s/$/ eth0/p}' file
192.168.0.12 80 eth0
127.0.0.1 80 eth0
I came here looking for the same answer, but none of the above do it as clean as
sed -i 's/address=.*/& eth0/g' file
Search and replace inline with sed for lines begining with address, replace with the same line plus 'eth0'
eg.
sed -i 's/address=.*/& eth0/g' file; cat file
junk line
address=192.168.0.12:80 eth0
address=127.0.0.1:25 eth0
don not match this line
All you need is:
awk -F'[=:]' '{print $2, $3, "eth0"}' file.txt |
while IFS= read -r ip port eth
do
printf "ip=%s, port=%s, eth=%s\n" "$ip" "$port" "$eth"
done
Always use IFS= and -r when using read unless you have a very specific reason not to. google for why.
typeset TMP_FILE=$( mktemp )
touch "${TMP_FILE}"
cp -p filename "${TMP_FILE}"
sed -e 's/$/stringToAdd/' "${TMP_FILE}" > filename
is this ok for you?
kent$ echo "xxx.xx.xx.xxx port1
xxx.xx.xx.xxx port2"|sed 's/.*/& eth0/'
xxx.xx.xx.xxx port1 eth0
xxx.xx.xx.xxx port2 eth0
P.S you could merge your cut, tr (even grep in your example) into one sed/awk call, to make the cmdline simpler and faster.

using awk within loop to replace field

I have written a script finding the hash value from a dictionary and outputting it in the form "word:md5sum" for each word. I then have a file of names which I would like to use to place each name followed by every hash value i.e.
tom:word1hash
tom:word2hash
.
.
bob:word1hash
and so on. Everything works fine but I can not figure out the substitution. Here is my script.
$#!/bin/bash
#/etc/dictionaries-common/words
cat words.txt | while read line; do echo -n "$line:" >> dbHashFile.txt
echo "$line" | md5sum | sed 's/[ ]-//g' >> dbHashFile.txt; done
cat users.txt | while read name
do
cat dbHashFile.txt >> nameHash.txt;
awk '{$1="$name"}' nameHash.txt;
cat nameHash.txt >> dbHash.txt;
done
the line
$awk '{$1="$name"}' nameHash.txt;
is where I attempt to do the substitution.
thank you for your help
Try replacing the entire contents of the last loop (both cats and the awk) with:
awk -v name="$name" -F ':' '{ print name ":" $2 }' dbHashFile.txt >>dbHash.txt

SED: First and last empty lines not removed

I'm running the following but it's returning with empty lines at the top and bottom of the new file.
How do I output to a new file without these empty lines?
input | sed -E '/^$/d' > file.txt
The following has no effect either.
sed '1d'
sed '$d'
I'm unsure of where the expression has problems.
If you are comfortable using awk then this would work -
awk 'NF' INPUT_FILE > OUTPUT_FILE
grep . file_name > outfile would do the job for you.
This might work for you:
echo -e " \t\r\nsomething\n \t \r\n" | sed '/^\s*$/d' | cat -n
1 something
N.B. This removes all blank lines, to preserve blank lines in the body of a file use:
echo -e " \t\r\n something\n \nsomething else \n \t \r\n" |
sed ':a;$!{N;ba};s/^\(\s*\n\)*\|\(\s*\n\)*$//g'
something
something else

Resources