sed: 패턴을 변수 목록으로 한 번만 교체

sed: 패턴을 변수 목록으로 한 번만 교체

저는 sed를 처음 사용하고 매번 패턴을 다른 변수로 바꾸는 방법을 알고 싶습니다.

아래와 같은 txt 파일이 있습니다.

@K3KFV:1:1109:11598:25872
@K3KFV:1:2101:22577:15247
@K3KFV:1:1110:13477:13178
@K3KFV:1:2113:23585:6859... (etc)

총 200개의 다양한 라인이 있습니다. 또한 다른 파일이 있습니다.

ASF356_KB822565.1:1065516-1065795
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT
 
ASF356_KB822565.1:1065796-1066075
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG
 
ASF356_KB822565.1:1066076-1066355
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTCA

또한 "ASF...."의 200개 인스턴스도 포함되어 있습니다.

내가 원하는 것은 "ASF..."가 포함된 줄을 "@K3KFV:....."의 줄로 바꾸는 것이므로 결국 다음과 같습니다.

@K3KFV:1:1109:11598:25872
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT

@K3KFV:1:2101:22577:15247
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG

@K3KFV:1:1110:13477:13178
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTCA

이것은 지금까지 내 쉘 스크립트입니다.

input="K3KFVfile.txt"

while IFS= read -r title
do
        sed '/ASF/c'$title'' ASF_file
done < "$input"

하지만 @K3KFV 200줄을 주는 대신... 모든 ASF 줄이 모든 @K3KFV 줄로 대체되었기 때문에 40000줄을 얻었습니다.

계속하기 전에 sed를 사용하여 패턴을 변수로 한 번만 바꾸는 방법이 있습니까? 이 경우 sed가 올바른 명령입니까?

답변1

sed의 GNU 구현이 있는 경우 (capital) 명령을 사용할 수 있습니다 R.GNU sed 관련 명령ASF- 두 번째 파일에서 -로 시작하는 라인과 일치할 때마다 첫 번째 파일의 라인을 읽고 삽입합니다. 그런 다음 일치하는 줄을 삭제합니다.

$ sed '/^ASF/{
R K3KFVfile.txt
d
}' ASF_file
@K3KFV:1:1109:11598:25872
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT

@K3KFV:1:2101:22577:15247
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG

@K3KFV:1:1110:13477:13178
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTCA

원한다면 다음과 같이 한 줄로 작성할 수 있습니다.

sed -e '/^ASF/{R K3KFVfile.txt' -e 'd}' ASF_file

아니면 awk 사용을 고려할 수도 있습니다.

awk 'NR==FNR{K[FNR] = $0; next} /^ASF/{$0 = K[++n]} 1' K3KFVfile.txt ASF_file

답변2

이 답변은 약간 즉흥적으로 작성되었습니다.@스틸드라이버

ASF_file의 빈 줄이 실제로 비어 있으면(공백 없음) 이 awk가 작동합니다.

awk '
    NR == FNR {x[FNR] = $0; next}
    {$1 = x[FNR]; print}
' K3KFVfile.txt RS='' ORS='\n\n' FS='\n' OFS='\n' ASF_file

두 번째 파일을 읽기 시작하기 전에 레코드와 필드가 결정되는 방식을 제어하기 위해 일부 awk 변수를 변경했습니다. 나는 보통 이런 스타일의 팬이 아니지만, 여기서는 잘 어울린다. 이 GNU awk 버전은 좀 더 깔끔합니다.

gawk '
    NR == FNR {x[FNR] = $0; next}
    ENDFILE {RS = ""; ORS = "\n\n"; FS = OFS = "\n"}
    {$1 = x[FNR]; print}
' K3KFVfile.txt ASF_file

답변3

사용 awk:

awk '/^ASF/ {getline < "@K3FVfile.txt"};1' ASF_file

같은 것 Perl:

perl -pe 's/^ASF.*/<STDIN>/se' ASF_file < @K3FVfile.txt

POSIXly sed를 사용하세요.

sed -n '/\n/bh
  1{
    :k3
      H;1h;n
    /^@K3KFV/bk3
  }
  /^ASF/g
  P;/\n.*\n/D
  s/.*\n//;th
  d;:h
  h
' @K3FVfile.txt ASF_file

Python에서 목록 이해 사용:

python3 -c 'import sys;a,b = sys.argv[1:]
with open(a) as f, open (b) as g:
  print(*[next(f) if l.startswith("ASF") else l for l in g],sep="",end="")
' @K3FVfile.txt ASF_file

산출:

@K3KFV:1:1109:11598:25872
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT
 
@K3KFV:1:2101:22577:15247
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG
 
@K3KFV:1:1110:13477:13178/
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTC

관련 정보