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
Running a Qt Application at Startup
Public Key Is Not Available: No_Pubkey F76221572C52609D
See Socket Options on Existing Sockets Created by Other Apps
Passing Associative Array as Argument with Bash
Executing Script on Receiving Incoming Connection with Xinetd
Redirect Stderr and Stdout to Separate Files in Bash
Accessing Shell Variable in a Perl Program
Return Code When Os Kills Your Process
Have 5 Scripts Running at Any Given Time
Clean Server Infected with C3284D Virus, Using Search and Replace
How to Download PHP Script from a Web Page with Wget
Create .So Files on Linux Without Using Pic (Position Independent Code) (X86 32Bit)
Comparing Variables with Strings Bash
How to Install Opencv on Amazon Linux
Unix File System: How Are File Names Translated to Disk Sectors
Assembly: Read Integer from Stdin, Increment It and Print to Stdout