How to Find Certain Character Position in Shell

How to find certain character position in shell

Using BASH:

a="This is test.txt file"
s="${a%%.*}" # remove all text after DOT and store in variable s
echo "$(( ${#s} + 1 ))" # get string length of $s + 1


Or using awk:

awk -F. '{print length($1)+1}' <<< "$a"

Search for specific characters in specific positions of line

To search for "foo" at position 42:

egrep '^.{42}foo'

You can run a command like this multiple times on your input:

egrep '^.{42}foo' inputfile.txt > lineswithfoo.txt
egrep '^.{42}bar' inputfile.txt > lineswithbar.txt

or as a loop:

for pattern in foo bar qux; do
egrep "^.{42}$pattern" inputfile.txt > lineswith$pattern.txt

How can I get a character of a string at a particular index?

The following script loops through all of the digits in the input string and adds them together:



for ((i=0; i<${#s}; ++i)); do

echo "sum of digits: $t"

The syntax ${s:i:1} extracts a substring of length 1 from position i in the string $s.


$ ./ 963
sum of digits: 18

If you wanted to continue adding together the digits until there was only one remaining, you could do this instead:



while (( ${#s} > 1 )); do
for ((i=0; i<${#s}; ++i)); do
echo "iteration $((++n)): $t"
echo "final result: $s"

The outer while loop continues as long as the length of the string is greater than 1. The inner for loop adds together each digit in the string.


$ ./ 963
iteration 1: 18
iteration 2: 9
final result: 9

Not that you asked for it but there are many ways to sum all of the digits in a string. Here's another one using Perl:

$ perl -MList::Util=sum -F -anE 'say sum @F' <<<639

List::Util is a core module in Perl. The sum subroutine does a reduction sum on a list to produce a single value. -a enables auto-split mode so the input is split into the array @F. -F is used to set the field delimiter (in this case it is blank, so every character counts as a separate field). -n processes every line of input one at a time and -E is used to enter a Perl one-liner but with newer features (such as say) enabled. say is like print but a newline is added to the output.

If you're not familiar with the <<< syntax, it is equivalent to echo 639 | perl ....

Cut string from position to character

If you want to stick with cut then this might be what you want:

echo 'Export text H8X7IS5G.FIC NB regs COLOLO 4138/4138' |
cut -c41- | cut -d/ -f1

There are many other ways to accomplish this task. If you have a grep which supports perl-compatible regular expressions, for instance, then I'd suggest something along this line:

grep -Po '.{40}\K[^/]*'

Or, a sed one-liner:

sed 's/.\{40\}//; s|/.*||'

Or, using pure bash

[[ $line =~ .{40}([^/]*) ]] && printf '%s\n' "${BASH_REMATCH[1]}"

Using sed command in shell script for substring and replace position to need

If you want to put the quotes in, I'd still use awk.

$: awk -F'|' 'BEGIN{q="\047"} {print  q $1 q","q substr($2,17,14) q","q $3 q","q $4 q"\n"}' <<< "X|001200000000000000000098765432|1234567890|TQ"

If you just want to use sed, note that you say above you want to remove 16 characters, but you are actually only removing 14.

$: sed -E "s/^(.)[|].{14}([^|]+)[|]([^|]+)[|]([^|]+)/'\1','\2','\3','\4'/" <<< "X|0012000000000000000098765432|1234567890|TQ"

Search Unix file name by positions of the characters in file name

Bash globbing has more than just *, e.g. ?, which means "any single character":

$ ls -1 ABC*C
$ ls -1 ABC????????0??
$ ls -1 ABC????????1??

Cut characters from position from string in bash

Agree with the answer by Charles Duffy. If you know you want specifically "JAC" instead of what indices you want removed, you could do:

echo "${str/JAC/}"

Related Topics

Leave a reply