Подтвердить что ты не робот

Строковая разница в Баш

Я пытаюсь найти способ определить разницу между двумя строками в моем скрипте. Я мог бы легко сделать это с помощью diff или comm, но я не имею дело с файлами, и я бы предпочел не выводить их в файлы, выполнить сравнение и прочитать его обратно.

Я вижу, что comm, diff, cmp все позволяют передавать либо два файла, либо файл и стандартный ввод - я думаю, это хорошо, если я не хочу выводить два файла... но это все равно отстой.

Я копался, думая, что могу использовать grep или регулярные выражения - но я думаю, что нет.

4b9b3361

Ответ 1

Используя diff или com или что угодно:

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

Greg Bash FAQ: Замена процесса

или с именованным каналом

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

Greg Bash FAQ: Работа с именованными каналами

Именованная труба также известна как FIFO.

- сам по себе предназначен для стандартного ввода.

<<< - это "настоящая строка".

& похож на ;, но помещает его в фоновый режим

Ответ 2

Напоминает мне об этом вопросе: Как вы можете разделить два конвейера в Bash?

Если вы находитесь в сеансе bash, вы можете сделать:

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

с < созданием анонимных именованных каналов - управляется bash - поэтому они создаются и уничтожаются автоматически, в отличие от временных файлов.

Итак, если вам удастся изолировать две разные строки как часть команды (grep, awk, sed,...), вы можете сделать - например, что-то вроде:

diff < grep string1 myFile < grep string2 myFile

(если вы предполагаете, что у вас есть в ваших файлах строки, такие как string1=very_complicated_value и string2=another_long_and_complicated_value': не зная внутреннего формата вашего файла, я не могу рекомендовать точную команду)

Ответ 3

Я предпочитаю cmp и функцию замены процесса bash:

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

Говоря о позиции 2, для первой появляется a b, а q для второго. В положении 5 происходит другое различие. Просто замените эти строки на переменные, и все готово.

Ответ 4

Скажем, у вас есть три строки

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

Чтобы удалить префикс b из

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

Чтобы удалить суффикс c из

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

Ответ 5

Другой пример:

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

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

Выходы

84192

Оригинальный ответ здесь