2015-01-19 4 views
-1

을 비교하면서 내가 선으로 두 파일 라인을 비교하면서, 즉,이 개 파일배쉬 쉘 스크립트 검사 2 개 파일

파일 1

abc 

cde 

efg 

hij 

jkl 

이제 파일 2

abc 

(*) (*) (*) -- without the braces 

efg 

(*) hij -- without braces 

(*) (*) lmn --- without braces 

을 가지고, file1의 첫 번째 줄은 file2의 첫 번째 줄과 만 비교됩니다.

abc ---- abc 

cde ---- * * * 
,451,515,

때 * *

hij --- (*) hij or jkl --- (*) (*) lmn 

hij을 비교하면서있는 File2의 hij과 비교해야하며, 다음 행 비교로 이동해야 다른 라인

그러나

을 비교를 발견하고 확인 하고, jkl해야을 부여해야 * lmn과 비교해야하며 알 수 없습니다. 어느 경우이든 * 또는 * *을 무시하십시오.

동일한 스크립트를 작성했습니다. 2 파일을 비교, 그러나 *에 대한 수표를 넣을 수 없습니다.

당신은 파일

# 1. Read lines from file1 as string, and file2 as comma-separated array. 

while read -r a && IFS=, read -ra b <&3; do 
# 2. If both empty lines, continue. 

if [[ "$a" == "" && ${#b[@]} == 0 ]]; then 

    continue 

fi 

# 3. Start assuming diff. 

diff=1 

# 4. Loop fields in $b. 

for e in ${b[@]}; do 

    # Compare field in $b with $a, if match then abort. 

    if [[ "$e" == "$a" ]]; then 

     diff=0 

     break 

    fi 

done 

# 5. If no match found, print line from $b. 

if [[ $diff == 1 ]]; then 

    # Join array with <space>comma. 

    line=$(printf ", %s" "${b[@]}") 

    # Print line, excluding leading <space>comma. 

    printf "%s\n" "${line:2}" 

fi 

# Input argument one as file 1 to stdin, and argument two as file 2 to 

# file descriptor 3. 

done < "$1" 3<"$2" 
+0

요구 사항을 명확히 할 수 있습니까? 파일 b의 줄에있는 어떤 단어 (즉,'$ {b [@]} '의 요소가 하나의 별표 ('*')로만 구성되어 있다면, 당신은 전체 라인 쌍? – bgoldst

+0

no .. 파일 b의 줄에 단일 또는 이중 astrix (*)가 있지만 값이 나중에 있으면 file1과 비교해야합니다. 그러나 b 파일의 줄에 3 (최대) (*)가 포함되어 있으면 비교를 위해 두 파일 모두 다음 줄로 이동해야합니다. –

+0

[모든 SO 교환에 동일한 질문을 다시 보내지 마십시오.] (http : // unix. stackexchange.com/questions/179839/bash-shell-scripting-check-while-comparing-2-files) –

답변

0

하나의 별표 (*) 및 두 개의 별표의 경우 이미 스크립트에 의해 제대로 처리되고 비교 스크립트 같은

발췌문 저를 도와 주실 수 있습니다. 귀하의 스크립트는 diff = 1로 가정하고, 일치하는 것이 발견되면 diff = 0으로 변경됩니다. 정확히 하나의 별표로 구성되는 ${b[@]}의 요소는 file1의 입력 행과 동일하지 않습니다. 즉, 원래의 가정 (diff = 1)을 그대로 유지합니다. 그러나 file1의 입력 행이 정확히 하나의 별표로 구성되어 있으면 비교 결과가 일치하고 diff = 0으로 설정됩니다. 그러나 file2에서 단일 별표의 의미는 다소 모호해집니다. "file1의 리터럴 단일 별표 행 일치"를 의미합니까, 아니면 "file1의 모든 줄과 일치하지 않습니까?"라는 뜻입니까? 후자의 의미는 file2의 별표를 의미하는 것으로 생각됩니다. 당신이 그 감각이 이상한 경우 유지 싶어, 당신은 파일 2에서 별표 단어를 건너 명시 적 검사를 추가해야 할 것 :

if [[ "$e" == '*' ]]; then continue; fi; 

이 테스트를 for 루프의 시작에 갈 것 .

세 개의 별표와 관련하여이 경우를 완전히 건너 뛰고 싶은 것처럼 들립니다. 앞에서 설명한 것처럼 현재 file2의 단일 별표 요소는 diff = 1을 유지하고 * * * 메시지가 인쇄되는 결과를 낳습니다 (file1의 입력 줄과 일치하지 않으므로). 다음과 같이이를 방지하기 위해, 당신은 * * *에 대해 명시 적으로 경비를 추가 할 수 있습니다

if [[ ${#b[@]} -eq 3 && "${b[0]}" == '*' && "${b[1]}" == '*' && "${b[2]}" == '*' ]]; then continue; fi; 

이 테스트는 빈 줄 체크 후 while 루프의 시작 근처에 갈 것입니다.

+0

감사합니다. 실제로 내 편이 이해가 잘못되었습니다 그래서 b []에 (*)가 포함되어 있으면 (*) (*) - 3 astreisk의 파일 B에서 해당 줄을 건너 뛰고 파일 b의 다음 줄을 file1과 비교해야합니다. 어떻게해야합니까? –

+0

b []에 별표 세 개가 포함되어 있으면 file2에서 해당 줄을 건너 뛰지 만 file1에서 줄을 건너 뛰지 마십시오. 즉 줄 비교 대상 줄 번호가 필요합니다. 동기화되지 않게하려면? – bgoldst

0

아래 해결책을 선호합니다. bash 매개 변수 확장 기능을 사용하여 스크립트를 단순화하는 선행 별표를 무시할 수 있습니다.

bash 매뉴얼, "매개 변수 확장"을 참조하십시오.

출력에 별표를 사용하지 않으려면 if 문에 사용 된 매개 변수 확장 결과를 별도의 변수에 할당하고이를 비교에 사용해야합니다.

while read -r a && IFS=, read -ra b <&3 
do 

    # If both lines are empty, continue. 
    if [ -z "$a" ] && [ -z "$b" ] 
    then 
     continue 
    fi 

    # If b contains three stars, don't compare. 
    if [ "$b" == "***" ] 
    then 
     continue 
    fi 

    # compare a and b ignoring leading * 
    if [ "$a" == "${b##\*}" ] 
    then 
     echo "$a: ok" 
    else 
     echo "$a/$b: nok" 
    fi 
done < "$1" 3<"$2" 

게다가, 미리 파일에서 빈 줄을 제거 돌볼 것입니다 및 오류를 일치하지 방지하기 위해, 두 개의 입력 파일의 줄 수를 확인합니다.