calculate count of char use in string - string

I'm trying to make this program work and I can't, The script i want must should calculate count of char use in string
example :
string=good
result=g1o2d1
is there any way to write script that calculate exactly count of string like my example or not ?
#!/bin/bash
string=ssstttrrrriiiinnnnngg
z=$( for((i=0;i<${#string};i++)) do; echo ${string:i:1}; done | uniq -c )
echo $z
my result :
s 3 t 3 r 4 i 4 n 5 g 2
but for analysis some document i want script to calculate char some like
firstchar1=$( bash script )
......
i need that value for use another script
please advise me
regards

$ echo "abaaacdefg" | grep -o .
a
b
a
a
a
c
d
e
f
g
$ echo "abaaacdefg" | grep -o .| sort
a
a
a
a
b
c
d
e
f
g
$ echo "abaaacdefg" | grep -o .| sort | uniq -c
4 a
1 b
1 c
1 d
1 e
1 f
1 g
$ echo "abaaacdefg" | grep -o .| sort | uniq -c | awk '{printf $2$1}'
a4b1c1d1e1f1g1
See
Bash: Split string into character array and
counting duplicates in a sorted sequence using command line tools

Related

Removing the new line in the last line of a text file using sed

I wanna remove the new line in the last line of my text file using sed. For example the input is like the following:
1
1
1
1
1
1
And I want to have an output like this without any new lines at the end of the text file:
1
1
1
1
1
1
This might work for you (GNU sed):
sed -z 's/\n\+$//' file
This will remove a newline(s) at the end of a file provided there are no null characters.
N.B. Normal use of sed i.e. without the -z option which slurps the file into memory, will remove any newlines before the sed commands can act on them.
Using sed
sed '/^$/d' input_file
This will remove all empty lines
Starting with some test data:
$ printf "%s\n" {a..e} "" "" | cat -n
1 a
2 b
3 c
4 d
5 e
6
7
I would approach the problem like this: reverse the file, remove blank lines
at the top, then re-reverse the file
$ printf "%s\n" {a..e} "" "" | tac | awk 'NF && !p {p=1}; p' | tac | cat -n
1 a
2 b
3 c
4 d
5 e
NF is the awk variable for "number of fields in this record". p is a variable I'm using to indicate when to start printing. The first time that NF is non-zero, we set the p variable to a true value. The standalone p at the end triggers the default action to print the record.
Removing the newline on the last line is a different story.
Given this file:
$ cat > file
first
second
third
$ od -c file
0000000 f i r s t \n s e c o n d \n t h i
0000020 r d \n
0000023
We can use perl:
$ perl -i -0777 -ne 's/\n+$//; print' file
$ od -c file
0000000 f i r s t \n s e c o n d \n t h i
0000020 r d
0000022
or tr to translate newlines to some other character, and sed to remove the trailing character
$ tr '\n' '\034' < file | sed $'s/\034$//' | tr '\034' '\n' | od -c
0000000 f i r s t \n s e c o n d \n t h i
0000020 r d
0000022

Shrink rows of one column with the same other column Linux

i have data in following form:
a, 1
a, 2
a, 3
b, 4
b, 5
b, 6
I would like to achieve it in the following form using bash commands:
a, "[1, 2, 3]"
b, "[4, 5, 6]"
the thing with the quotes and square brackets is not that relevant as just having in second column a collection of items having the same value in the first one.
Absolutely in-efficient way (you should use awk or perl)
file="file.txt"
while read -r k
do
printf '%s, "[%s]"\n' "$k" "$(paste -sd, <(grep -oP "^$k\s*,\s*\K.*" "$file"))"
done < <(cut -d, -f1 "$file" | sort -u)
output:
a, "[1,2,3]"
b, "[4,5,6]"
form.txt
a, 1
a, 2
a, 3
b, 4
b, 5
b, 6
script.sh
#! /bin/bash
set -o errexit # Exit if there is an error
form=${1?"Expected form as argument"}
while read -r line; do
cmd="${line/,[[:space:]]/+=(})"; # replace line with "var+=(val)"
eval ${cmd}; # Process the command, add the value to the array.
done < "${form}"
while read -r array; do
eval echo "${array} [\${$array[#]}]"; # Should print array (val val val)
done < <(cut -f1 -d"," "${form}" | sort | uniq) # Get all the array names
This script should do what you want.

Why does wc count one extra character in my file? [duplicate]

This question already has an answer here:
wc -m in unix adds one character
(1 answer)
Closed 6 years ago.
1.) I am using Debian 8.4 on a virtual box and as I ran the command wc sample.txt to sample.txt containing:
Hello
The output to the command was
1 1 6 sample.txt
Is the extra character EOF? If it is then how come when I ran the same command for an empty file the output was..
0 0 0 sample.txt
You have a trailing new line and this is what wc reports.
See for example if we create a file with printf:
$ printf "hello" > a
$ cat a | hexdump -c
0000000 h e l l o
0000005
$ wc a
0 1 5 a
However, if we write with something like echo, a trailing new line is appended:
$ echo "hello" > a
$ cat a | hexdump -c
0000000 h e l l o \n
0000006
$ wc a
1 1 6 a

How to get a single output file with N lines from N multiline files?

I am looking for some effective way to concatenate multiple multiline files into one file - here is an example for three input files:
1.txt:
a b
c d
2.txt:
e f
g
h
3.txt:
ijklmn
output.txt:
a b c d
e f g h
ijklmn
(Replacing each linebreak with single whitespace). Which way can you recommend?
Using BASH for loop:
for i in [0-9]*.txt; do tr '\n' ' ' < "$i"; echo; done > output.txt
cat output.txt
a b c d
e f g h
ijklmn
If you want to strip one ending space before each line break then use:
for i in [0-9]*.txt; do tr '\n' ' ' < "$i"; echo; done | sed 's/ *$//' > output.txt

"Minus" operation on two files using Linux commands

I have 4 files sorted alphabetically, A, B, C, and D.
These files contain a single string on each line.
Essentially, what needs to happen is that anything in B gets deleted from A.
The result of that will then be stripped of anything in C.
And similarly, the result of that will be stripped of D.
Is there a way to this using Linux commands?
comm is good for this, either:
cat B C D | sort | comm -2 -3 A -
or:
comm -2 -3 A B | comm -2 -3 - C | comm -2 -3 - D
depending on what's easier/clearer for your script.
grep -x -v -f B A | grep -x -v -f C | grep -x -v -f D
The -v switch is an inverse match (i.e. match all except). The -f switch takes a file with a list of patterns to match. The -x switch forces it to match whole lines (so that lines that are substrings of other lines don't cause the longer lines to be removed).
Look at the join command. Read its man page and you should find what you seek.
join A B | join - C | join - D

Resources