Position of a String Within a String Using Linux Shell Script

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

13

Or using awk:

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

Print the index of a substring in a string in Bash

You are checking if both strings are equal, which of course most of the time they are not.

if [[ "$a" == "$b" ]]

Probably you mean

if [[ $a == *"$b"* ]]

where perhaps also notice that [[ is more relaxed when it comes to quoting.

Notice also that the file's very first two bytes need to be #! in order for the first line to be a valid shebang; you show yours as indented by one space, which will not work.

A better design than read is to accept the parameters as command-line arguments; then, the user gets the benefits of command-line history, variables, tab expansion, etc.

#!/bin/bash

if [[ $1 == *"$2"* ]]; then
rest=${1#*$2}
echo $(( ${#1} - ${#rest} - ${#2} +1 ))
else
echo "-1"
fi

If you do use read, probably use read -r; the option disables some legacy behavior around backslashes which you basically never want to experience.

BASH Script to find a string in a file by position, match, then modify that position and insert if it exists

Rewriting the input file repeatedly is horrendously inefficient. You want to perform all the replacements in one go.

sed is rather hard to read once you start doing nontrivial things, so I would recommend switching to Awk (or a proper modern scripting language like Python if you want to invest more into this).

awk -F , 'BEGIN { OFS=FS
pos = "{ABCDEFGHI"; neg = "}JKLMNOPQR";
for (i=0; i<10; ++i) { p[substr(pos, i+1, 1)] = i; n[substr(neg, i+1, 1)] = i }
}
{ for (i=4; i<=5; i++) {
where = length($i)
what = substr($i, where, 1)
if (what ~ "^[" pos "]$") sign = ""
else if (what ~ "^[" neg "]$") sign = "-"
else print "Error: field " i " " $i " malformed" >"/dev/stderr"
$i = sign substr($i, 1, where-1) (sign ? n[what] : p[what])
}
}1' input.in

Demo: https://ideone.com/z8wK0V

This isn't entirely obvious, but here's a quick breakdown.

In the BEGIN block, we create two associative arrays, such that

p["{"] = 0, n["}"] = 0
p["A"] = 1, n["J"] = 1
p["B"] = 2, n["K"] = 2
p["C"] = 3, n["L"] = 3
p["D"] = 4, n["M"] = 4
p["E"] = 5, n["N"] = 5
p["F"] = 6, n["O"] = 6
p["G"] = 7, n["P"] = 7
p["H"] = 8, n["Q"] = 8
p["I"] = 9, n["R"] = 9

(We also set OFS to FS so that Awk will print the output comma-separated, like it reads the input.)

Down in the main block, we loop over fields 4 and 5, extracting the last character and mapping it to the corresponding entry from the correct one of the two arrays, and add a sign if warranted.

This simply writes to standard output; save to a new file and move it back over the original input file, or if you have GNU Awk, explore its -i inplace option.

If you really wanted to do this in sed, it offers a rather convenient y/{ABCDEFGHI/0123456789/ but picking apart the fields and then reassembling the line when you are done is not going to be pleasant.

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"
'X','00000098765432','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"
'X','00000098765432','1234567890','TQ'

how to find the position of a string in a file in unix shell script

awk variables are not the same as shell variables. You need to define them with the -v flag

For example:

$ awk -v var="..." '$0~var{print NR}' file

will print the line number(s) of pattern matches. Or for your case with the index

$ awk -v var="$Var" 'p=index($0,var){print NR,p}' file

using all uppercase may not be good convention since you may accidentally overwrite other variables.

to capture the output into a shell variable

$ info=$(awk ...)

for multi line output assignment to shell array, you can do

$ values=( $(awk ...) ); echo ${values[0]}

however, if the output contains more than one field, it will be assigned it's own array index. You can change it with setting the IFS variable, such as

$ IFS=$(echo -en "\n\b"); values=( $(awk ...) )

which will capture the complete lines as the array values.



Related Topics



Leave a reply



Submit