Строковая разница в Баш - PullRequest
94 голосов
/ 18 января 2009

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

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

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

Ответы [ 5 ]

161 голосов
/ 18 января 2009

Использование diff или com или что вы хотите:

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

Greg's Bash FAQ: Процесс замены

или с именованной трубой

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

FAQ Грега по Bash: Работа с именованными каналами

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

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

<<< - это строка здесь.

& похоже на ;, но помещает его на задний план

13 голосов
/ 18 января 2009

Напоминает мне этот вопрос: Как вы можете использовать два конвейера в 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': не зная внутреннего формата вашего файла, я не могу порекомендовать точную команду)

12 голосов
/ 18 января 2009

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

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

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

11 голосов
/ 08 сентября 2014

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

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

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

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

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

echo ${a%"$c"}  # this is
0 голосов
/ 10 мая 2019

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

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

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

Выходы

84192

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...