두 개의 파일이 있습니다.
파일 1:
ABA
FFR
HHI
HAB
파일 2:
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
file1의 각 줄은 file2의 해당 줄 시작 부분에서 반복되는 패턴입니다. file1에서 반복되는 패턴이 아닌 file2의 각 줄 부분을 가져오고 싶습니다.
원하는 출력:
TRCFUJIKHRTHVFHJJHVHJJKKHGCC
FHJKGHKKBVDTHJNJ
DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
GTHFOOLLLHHHUUJCIICXXTKCIABAGGC
나는 이 루프를 사용하려고 합니다:
while read -r line
do
grep -v "$line{1,}" file2.txt
done < file1.txt
그러나 나는 다음과 같은 결과를 얻습니다.
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
답변1
ABA
변수에 eg를 사용하면 grep -v "$line{1,}"
grep에 패턴이 제공됩니다 . 즉, 하나 , 하나 , 그리고 적어도 하나를 ABA{1,}
찾습니다 . 마지막 반복은 중요하지 않습니다. 그 이후에는 아무것도 없기 때문에 한 번의 반복이라도 일치합니다.A
B
A
ABA
음, 기본적으로 grep은 다음과 같이 계산된 반복을 백슬래시로 작성해야 하는 기본 정규 표현식(BRE)을 사용한다는 점만 제외하면 됩니다. 확장 정규 표현식(ERE)에서는 한 번 이상의 반복이 발생하지만 BRE에서는 리터럴 문자 4개(일반 문자이기도 함)입니다.\{n,m\}
{1,}
+
+
그러나 grep은 전체 내용을 인쇄합니다.철사일치하거나 -v
일치하지 않습니다. 행의 일부를 삭제하지 않습니다. ( grep -o
일치하는 부분만 인쇄하는 경우를 제외하고는 적용되지 않는다고 생각합니다 -v
.) 또한 해당 루프를 통해 grep
다음과 같이 보일 것입니다 .모두각 패턴에 대한 행이 있으므로 file2
콘텐츠가 여러 번 반복됩니다.
각 반복의 각 입력에서 한 줄을 읽는 루프가 필요합니다. 셸에서 수행할 수 있지만 속도가 매우 느립니다. AWK와 같은 것이 더 좋습니다. 예를 들면 다음과 같습니다.
$ awk '{getline pat < "file1"; sub("^(" pat ")*", ""); print}' file2
TRCFUJIKHRTHVFHJJHVHJJKKHGCC
FHJKGHKKBVDTHJNJ
DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
GTHFOOLLLHHHUUJCIICXXTKCIABAGGC
AWK 프로그램은 라인(및 명령줄에 제공된 다른 파일)을 통해 암시적으로 반복됩니다. 여기서는 file2
각 반복에서 명시적으로 한 줄을 읽습니다. file1
그런 다음 현재 줄과 일치하는 "^(" pat ")*"
유사한 패턴을 구성 하고 이를 빈 문자열로 바꿉니다.^(ABA)*
이렇게 하면 행에서 패턴의 추가 인스턴스가 제거되지 않으며 예를 ABAABAFOOABABAR
들어 가 됩니다 FOOABABAR
. 해당 항목도 제거하려면 으로 변경하세요 gsub("(" pat ")*", "");
.
답변2
사용된 솔루션은 awk
각 행의 해당 행에서 반복되는 패턴을 제거합니다.file1
file2
awk 'NR==FNR { pattern[NR]="^(" $0 ")*"; next } { sub(pattern[FNR], ""); print }' file1 file2
설명하다:
NR==FNR
첫 번째 파일만 일치하는 조건입니다.pattern[NR]="^(" $0 ")*";
문자열에서 패턴을 구성하고 현재 줄 번호를 인덱스로 사용하여 배열에 추가합니다.ABA
-> =^\(ABA\)*
줄 시작 부분에 반복되는 문자열의 수입니다.ABA
next
모든 추가 처리를 건너뜁니다. 이로 인해 다음 작업이 두 번째(및 후속) 파일에만 적용됩니다.sub(pattern[FNR], "")
현재 줄 번호를 빈 문자열로 바꾸는 패턴print
(수정된) 줄을 인쇄하세요
가능한 해결책은 이것을 사용하여 모든 행의 모든 패턴을 awk
제거합니다 .file1
file2
awk 'NR==FNR { pattern[count++]="^(" $0 ")*"; next } { for(i = 0; i < count; i++) sub(pattern[i], ""); print }' file1 file2
설명하다:
NR==FNR
첫 번째 파일만 일치하는 조건입니다.pattern[count++]="^(" $0 ")*";
문자열에서 패턴을 구성하고 이를 배열에 추가합니다.ABA
-> =^(ABA)*
줄 시작 부분에 반복되는 문자열의 수입니다. 처리된 행의 수입니다.ABA
count
file1
next
모든 추가 처리를 건너뜁니다. 이로 인해 다음 작업이 두 번째(및 후속) 파일에만 적용됩니다.for(i = 0; i < count; i++)
모든 패턴을 순환합니다.sub(pattern[i], "")
패턴을 빈 문자열로 바꾸기print
(수정된) 줄을 인쇄하세요
답변3
while read
-bash-loop 메소드에 따르면 sed
다음 기술을 구현할 수 있습니다.
#!/bin/bash
i=0
while read pat ; do
((i++))
sed -n "${i}s/^\($pat\)\{1,\}//g;${i}p" file2
done < file1
"반복 패턴"에 대한 귀하의 설명이 약간 혼란스럽습니다. 적어도 두 번은 나타나야 한다고 생각합니다. 예를 들어 \{2,\}
제게는 그것이 더 적절하다고 느껴질 것입니다.
답변4
그게 다야, 친구:
challenge.sh
#!/bin/bash
readarray -t searchStrs < file1.txt
linesInFile=$((${#searchStrs[@]} - 1))
line=0
while [ ${line} -le ${linesInFile} ]
do
srchStr=$(echo ${searchStrs[$line]})
result=$(grep -E "^${srchStr}" file2.txt | sed "s@${srchStr}@@g")
line=$((${line} + 1))
echo ${result}
done
./challenge.sh
TRCFUJIKHRTHVFHJJHVHJJKKHGCC
FHJKGHKKBVDTHJNJ
DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
GTHFOOLLLHHHUUJCIICXXTKCIABAGGC
cat file2.txt
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC
FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ
HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII
HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC