Bash의 문자열 차이


110

내 스크립트에서 두 문자열의 차이를 확인하는 방법을 찾으려고합니다. diff 또는 comm으로 쉽게 할 수 있지만 파일을 다루지 않고 파일로 출력하지 않고 비교하고 다시 읽는 것을 선호합니다.

comm, diff, cmp 모두 두 파일 또는 파일과 표준 입력을 전달할 수 있습니다. 두 파일을 출력하지 않으려면 좋을 것 같지만 여전히 약간 짜증납니다.

grep 또는 정규식을 사용할 수 있다고 생각하고 있었지만 그렇지 않은 것 같습니다.


1
실제로하고 싶은 것이 무엇입니까?

IFS 변경 사항과 함께 하위 문자열 조작 및 내장 테스트 작업을 사용하여 비교할 수 있지만 문자, 단어, 한 줄씩 비교하고 공백을 무시
할지 여부를 알아야

답변:


198

사용 diff하거나 com또는 당신이 원하는대로 :

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

Greg의 Bash FAQ : 프로세스 대체

또는 명명 된 파이프

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

Greg의 Bash FAQ : 명명 된 파이프 작업

명명 된 파이프는 FIFO라고도합니다.

-그 자체는 표준 입력을위한 것입니다.

<<< "여기 문자열"입니다.

&비슷 ;하지만 배경에 넣습니다


5
정답은 +1. 기호에 대한 훌륭한 설명은 +1. 또한 Greg의 Bash FAQ가 다음으로 이동했습니다. mywiki.wooledge.org 위 페이지의 링크는 현재 mywiki.wooledge.org/ProcessSubstitutionmywiki.wooledge.org/BashFAQ/085에 있습니다
timemachine3030

고마워! 또한 동적 파일 설명자가 표시됩니다FUNC(){ echo "$@"; "$@"; }; FUNC diff <(echo a) <(echo b);
Aquarius Power

나는 두 개의 shasum을 비교하기 위해 그것을 찾고 있었다. 더 우아한 방법이 있는지 확실하지 않지만 작동합니다.
fuma

이것은 $ string1 및 $ string2에 여러 줄이있는 경우 작동하는 것처럼 보이고 diff는 더하거나 뺀 줄을 출력합니다. 문자열이 한 줄이고 줄이고 두 문자열간에 약간의 차이가 있으면 어떻게됩니까?
alpha_989

@ alpha_989, 대답 $ diff <(echo "Here are the letters in String One.") <(echo "Here are the characters in String Two.") \n 1c1 \n < Here are the letters in String One. \n --- \n > Here are the characters in String Two. \n은 다음과 같습니다 . 파이프를 사용하는 것은 프로세스 번호가 표시되고 다음 1c1이후로 시작하고 $<kbd> Enter <kbd>를 누를 때까지 기다린다 는 점을 제외하면 비슷합니다 (또는 다른 명령을 수행 할 수 있습니다 ...).
bballdave025

19

이 질문을 상기시킵니다. Bash에서 두 파이프 라인을 어떻게 비교할 수 있습니까?

bash 세션에있는 경우 다음을 수행 할 수 있습니다.

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

<bash에 의해 관리 - - 자신이 만든 임시 파일과 달리, 자동 파괴되도록 익명 명명 된 파이프를 생성.

따라서 명령 (grep, awk, sed, ...)의 일부로 두 개의 다른 문자열을 분리 할 수 ​​있다면 다음과 같이 할 수 있습니다.

diff < grep string1 myFile < grep string2 myFile

(파일 줄에 string1=very_complicated_valuestring2=another_long_and_complicated_value' 의 내부 형식을 모르고 : 정확한 명령을 권장 할 수 없습니다)


13

나는 cmpbash의 대체 기능을 선호 하고 처리합니다.

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

위치 2에서 ab는 첫 번째에 발생하지만 aq는 두 번째에 발생합니다. 위치 5에서 또 다른 차이가 발생합니다. 해당 문자열을 변수로 바꾸면 완료됩니다.


이것은 문자열의 길이가 같은 경우에만 작동합니다!
strpeter 2016 년

11

세 줄이 있다고 가정 해 보겠습니다.

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

a에서 접두사 b를 제거하려면

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

a에서 접미사 c를 제거하려면

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

2
나는 이것이 그것을하는 bash 방법이라고 생각합니다. 잘 작동했습니다. 그 구문은 이해하기 조금 어렵습니다.
Mikael Roos 2014

@MikaelRoos 동의합니다. (어쨌든 나를 위해) 더 쉽게 읽을 수있는 방법은 sed를 사용하는 것입니다 : echo "$a" | sed "s!^$b!!g" (처리되는 변수가 경로 인 경우 표준 sed 구분 기호 / for!를 교체했습니다. 또한 echo : 대신 here 문자열을 사용할 수 있습니다 sed ... <<< $a.)
ACK_stoverflow

1

다른 예시:

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

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

출력

84192

여기에 원래 답변

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.