저는 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