Setting last digit of a number to a variable in a shell script - bash

I have a number 2014061200 and I am trying to extract the one's digit of this number (0) and set it to a variable $STR, so that $STR would equal 0, because that is in the one's place of the above number.
I made a shell script showing the following:
$NUM=2014061200
$STR= $NUM | tail -c 2
echo $STR
However when I do this I get a blank for $STR instead of the expected result of 0. I mean when I type
echo $NUM | tail -c 2, I do get the output of 0, but how do I get this into a variable?
Thanks

Use parameter expansion:
num=2014061200
last=${num: -1}
-1 tells bash to extract one character from the right.

Here's another variation using parameter expansion where ${#num}-1 is the length of the string less 1 and ${num:position:length} is a substring expression:
${num:(${#num}-1):1}

Related

Bash increment length of string

I just want to echo an incremented string length. For example:
STR="test"
echo ${#STR}
It prints 4, but I want to print 5.
STR="test"
count=${#STR}
((count++))
echo $count
((count++)): How to increment a variable in bash?
The length of the string cannot be changed without modifying the string. If you want to add another character at the beginning, try
STR="a$STR"
Now ${#STR} is 5, because STR is atest (five characters).
If you want to perform arithmetic in the shell, use an arithmetic expression:
echo "$((1+${#STR}))"

Save highest file extension to a variable

I've got files where the extension is a number:
backup.1
backup.2
backup.3
I now need to check what the highest number is and save this number into a variable. (In the case above it would be i=3)
The problems is actually fairly simple in bash. Bash provides a parameter expansion with substring removal that makes it easy to obtain the final number from the filename. It has the form ${var##*.} which simply searches from the left of the string to the last occurrence of '.' removing all character up to, and including the dot, e.g.
var=backup.1
echo ${var##*.}
1
So all you need to is loop over all files matching backup.[0-9]* and keep a max variable holding the highest number seen, e.g.
max=0
for i in backup.[0-9]*; do
[ "${i##*.}" -gt $max ] && max="${i##*.}"
done
echo "max: $max"
Output based on your files,
max: 3
Look things over and let me know if you have further questions.
highest=$(ls backup* | sort -t"." -k2 -n | tail -n1 | sed -r 's/.*\.(.*)/\1/')
My files:
backup.1
backup.2
backup.3
backup.4
backup.5
backup.6
backup.7
backup.8
backup.9
backup.10
Output:
echo "${highest}"
10

print upto second last character in unix

If the length of a string is 5 then how can I print upto 4th character of the string using shell scripting.I have stored the string in a variable and length in other variable.but how can i print upto length -1.
If you are using BASH then it is fairly straight forward to remove last character:
s="string1,string2,"
echo "${s%?}"
? matches any single character and %? removes any character from right hand side.
That will output:
string1,string2
Otherwise you can use this sed to remove last character:
echo "$s" | sed 's/.$//'
string1,string2
You can do it with bash "parameter substitution":
string=12345
new=${string:0:$((${#string}-1))}
echo $new
1234
where I am saying:
new=${string:a:b}
where:
a=0 (meaning starting from the first character)
and:
b=${#string} i.e. the length of the string minus 1, performed in an arithmetic context, i.e. inside `$((...))`
str="something"
echo $str | cut -c1-$((${#str}-1))
will give result as
somethin
If you have two different variables, then you can try this also.
str="something"
strlen=9
echo $str | cut -c1-$((strlen-1))
cut -c1-8 will print from first character to eighth.
Just for fun:
When you have the string and length in vars already,
s="example"
slen=${#s}
you can use
printf "%.$((slen-1))s\n" "$s"
As #anubhava showed, you can also have a clean solution.
So do not try
rev <<< "${s}" | cut -c2- | rev

Shell Bash Replace or remove part of a number or string

Good day.
Everyday i receive a list of numbers like the example below:
11986542586
34988745236
2274563215
4532146587
11987455478
3652147859
As you can see some of them have a 9(11 digits total) in as the third digit and some dont(10 digits total, that`s because the ones with an extra 9 are the new Brazilian mobile number format and the ones without it are in the old format.
The thing is that i have to use the numbers in both formats as a parameter for another script and i usually have do this by hand.
I am trying to create a script that reads the length of a mobile number and check it`s and add or remove the "9" of a number or string if the digits condition is met and save it in a separate file condition is met.
So far i am only able to check its length but i don`t know how to add or remove the "9" in the third digit.
#!/bin/bash
Numbers_file="/FILES/dir/dir2/Numbers_File.txt"
while read Numbers
do
LEN=${#Numbers}
if [ $LEN -eq "11" ]; then
echo "lenght = "$LEN
elif [ $LEN -eq "10" ];then
echo "lenght = "$LEN
else
echo "error"
fi
done < $Numbers_file
You can delete the third character of any string with sed as follows:
sed 's/.//3'
Example:
echo "11986542586" | sed 's/.//3'
1186542586
To add a 9 in the third character:
echo "2274563215" | sed 's/./&9/3'
22794563215
If you are absolutely sure about the occurrence happening only at the third position, you can use an awk statement as below,
awk 'substr($0,3,1)=="9"{$0=substr($0,1,2)substr($0,4,length($0))}1' file
1186542586
3488745236
2274563215
4532146587
1187455478
3652147859
Using the POSIX compliant substr() function, process only the lines having 9 at the 3rd position and move around the record not considering that digit alone.
substr(s, m[, n ])
Return the at most n-character substring of s that begins at position m, numbering from 1. If n is omitted, or if n specifies more characters than are left in the string, the length of the substring shall be limited by the length of the string s
There are lots of text manipulation tools that will do this, but the lightest weight is probably cut because this is all it does.
cut only supports a single range but does have an invert function so cut -c4 would give you just the 4th character, but add in --complement and you get everything but character 4.
echo 1234567890 | cut -c4 --complement
12356789

how to chop last n bytes of a string in bash string choping?

for example qa_sharutils-2009-04-22-15-20-39, want chop last 20 bytes, and get 'qa_sharutils'.
I know how to do it in sed, but why $A=${A/.\{20\}$/} does not work?
Thanks!
If your string is stored in a variable called $str, then this will get you give you the substring without the last 20 digits in bash
${str:0:${#str} - 20}
basically, string slicing can be done using
${[variableName]:[startIndex]:[length]}
and the length of a string is
${#[variableName]}
EDIT:
solution using sed that works on files:
sed 's/.\{20\}$//' < inputFile
similar to substr('abcdefg', 2-1, 3) in php:
echo 'abcdefg'|tail -c +2|head -c 3
using awk:
echo $str | awk '{print substr($0,1,length($0)-20)}'
or using strings manipulation - echo ${string:position:length}:
echo ${str:0:$((${#str}-20))}
In the ${parameter/pattern/string} syntax in bash, pattern is a path wildcard-style pattern, not a regular expression. In wildcard syntax a dot . is just a literal dot and curly braces are used to match a choice of options (like the pipe | in regular expressions), so that line will simply erase the literal string ".20".
There are several ways to accomplish the basic task.
$ str="qa_sharutils-2009-04-22-15-20-39"
If you want to strip the last 20 characters. This substring selection is zero based:
$ echo ${str::${#str}-20}
qa_sharutils
The "%" and "%%" to strip from the right hand side of the string. For instance, if you want the basename, minus anything that follows the first "-":
$ echo ${str%%-*}
qa_sharutils
only if your last 20 bytes is always date.
$ str="qa_sharutils-2009-04-22-15-20-39"
$ IFS="-"
$ set -- $str
$ echo $1
qa_sharutils
$ unset IFS
or when first dash and beyond are not needed.
$ echo ${str%%-*}
qa_sharutils

Resources