String difference in Bash

StringBash

String Problem Overview


I'm trying to find a way to determine the difference between two strings in my script. I could easily do this with diff or comm, but I'm not dealing with files and I'd prefer not to output them to files, do the compare and read it back.

I see that comm, diff, cmp all allow to pass either two files OR a file and standard input - I guess that's good if I don't want to output two files...but it's still kinda sucks.

Been digging around thinking I can use grep or regular expressions - but I guess not.

String Solutions


Solution 1 - String

Using diff or com or whatever you want:

diff  <(echo "$string1" ) <(echo "$string2")

Greg's Bash FAQ: Process Substitution

or with a named pipe

mkfifo ./p
diff - p <<< "$string1" & echo "$string2" > p

Greg's Bash FAQ: Working with Named Pipes

Named pipe is also known as a FIFO.

The - on its own is for standard input.

<<< is a "here string".

& is like ; but puts it in the background

Solution 2 - String

Reminds me of this question: How can you diff two pipelines in Bash?

If you are in a bash session, you could do a:

diff <cmd1 <cmd2
diff <(foo | bar) <(baz | quux)

with < creating anonymous named pipes -- managed by bash -- so they are created and destroyed automatically, unlike temporary files.

So if you manage to isolate your two different string as part of a command (grep, awk, sed, ...), you can do - for instance - something like:

diff < grep string1 myFile < grep string2 myFile

(if you suppose you have in your file lines like string1=very_complicated_value and a string2=another_long_and_complicated_value': without knowing the internal format of your file, I can not recommend a precise command)

Solution 3 - String

I prefer cmp and Process Substitution feature of bash:

$ cmp -bl <(echo -n abcda) <(echo -n aqcde)
  2 142 b    161 q
  5 141 a    145 e

Saying on position 2, a b occurs for the first, but a q for the second. At position 5, another difference is happening. Just replace those strings by variables, and you are done.

Solution 4 - String

Say you have three strings

a="this is a line"
b="this is"
c="a line"

To remove prefix b from a

echo ${a#"$b"}  # a line

To remove suffix c from a

echo ${a%"$c"}  # this is

Solution 5 - String

Another example:

before="184613 102050 83756 63054"
after="184613 102050 84192 83756 63054"

comm -23 <(tr ' ' $'\n' <<< $after | sort) <(tr ' ' $'\n' <<< $before | sort)

Outputs

84192

Original answer here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnewbrandView Question on Stackoverflow
Solution 1 - StringIan KellingView Answer on Stackoverflow
Solution 2 - StringVonCView Answer on Stackoverflow
Solution 3 - StringJohannes Schaub - litbView Answer on Stackoverflow
Solution 4 - StringPithikosView Answer on Stackoverflow
Solution 5 - StringSida ZhouView Answer on Stackoverflow