Строковая разница в Баш
Я пытаюсь найти способ определить разницу между двумя строками в моем скрипте. Я мог бы легко сделать это с помощью diff или comm, но я не имею дело с файлами, и я бы предпочел не выводить их в файлы, выполнить сравнение и прочитать его обратно.
Я вижу, что comm, diff, cmp все позволяют передавать либо два файла, либо файл и стандартный ввод - я думаю, это хорошо, если я не хочу выводить два файла... но это все равно отстой.
Я копался, думая, что могу использовать grep или регулярные выражения - но я думаю, что нет.
Ответы
Ответ 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
Оригинальный ответ здесь