Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Longest common prefix of two strings in bash

I have two strings. For the sake of the example they are set like this:

string1="test toast" string2="test test" 

What I want is to find the overlap starting at the beginning of the strings. With overlap I mean the string "test t" in my above example.

# So I look for the command  command "$string1" "$string2" # that outputs: "test t" 

If the strings were string1="atest toast"; string2="test test" they would have no overlap since the check starts from the beginning and the "a" at the start of string1 .

like image 809
con-f-use Avatar asked Aug 07 '11 13:08

con-f-use


People also ask

What is longest common prefix string?

Longest common prefix (LCP) for a pair of strings S1 and S2 is the longest string S which is the prefix of both S1 and S2. For Example: longest common prefix of “abcdefgh” and “abcefgh” is “ABC”.

How do you find the longest prefix in Python?

To solve this, we will take the first string as curr, now take each string from the array and read them character by character, and check the characters between curr, and the taken string one by one. If they are same go for next character, otherwise break the loop, and update the curr as the substring that has matched.


2 Answers

In sed, assuming the strings don't contain any newline characters:

string1="test toast" string2="test test" printf "%s\n%s\n" "$string1" "$string2" | sed -e 'N;s/^\(.*\).*\n\1.*$/\1/' 
like image 85
jfg956 Avatar answered Sep 20 '22 07:09

jfg956


An improved version of the sed example, this finds the common prefix of N strings (N>=0):

string1="test toast" string2="test test" string3="teaser" { echo "$string1"; echo "$string2"; echo "$string3"; } | sed -e 'N;s/^\(.*\).*\n\1.*$/\1\n\1/;D' 

If the strings are stored in an array, they can be piped to sed with printf:

strings=("test toast" "test test" "teaser") printf "%s\n" "${strings[@]}" | sed -e '$!{N;s/^\(.*\).*\n\1.*$/\1\n\1/;D;}' 

You can also use a here-string:

strings=("test toast" "test test" "teaser") oIFS=$IFS IFS=$'\n' <<<"${strings[*]}" sed -e '$!{N;s/^\(.*\).*\n\1.*$/\1\n\1/;D;}' IFS=$oIFS # for a local IFS: (IFS=$'\n'; sed -e '$!{N;s/^\(.*\).*\n\1.*$/\1\n\1/;D;}' <<<"${strings[*]}") 

The here-string (as with all redirections) can go anywhere within a simple command.

like image 20
ack Avatar answered Sep 23 '22 07:09

ack