일치하는 항목이 발견되면 파일 a의 하위 문자열을 파일 b의 문자열로 바꿉니다.

일치하는 항목이 발견되면 파일 a의 하위 문자열을 파일 b의 문자열로 바꿉니다.

2개의 파일이 있습니다.

파일 1

This is a string = mystringrocks
This is another string = mystringrocksmore

파일 2

Trying to figure out: This is a string
Still trying to figure it out: This is another string

원하는 출력:

Trying to figure out: mystringrocks
Still trying to figure it out: mystringrocksmore

나는 많은 것을 시도했는데 가장 최근에는 두 파일을 배열로 로드하고 sed 루프를 사용했습니다.

#!/bin/bash    
declare -a a
readarray a <filea.txt
echo $a

declare -a b
readarray b <fileb.txt
echo $b

for line in 'fileb.txt';
 do sed -i -- 's/$line/$a/' file.txt 
 done

소용이 없습니다.

답변1

sedfile1을 사용하여 스크립트를 생성한 후 이 스크립트를 실행하여 file2를 예상 출력으로 변환할 수 있습니다 .sedsed

sed 's!^!s/!;s! = !/!;s!$!/!' file1 | sed -f- file2

첫 번째 출력 sed은 다음과 같습니다.

s/This is a string/mystringrocks/
s/This is another string/mystringrocksmore/

필요한 교체 작업을 명확하게 수행합니다.

슬래시와 느낌표가 포함된 문자열에도 작동하는 Perl을 사용할 수도 있습니다.

perl -wE 'while (<>) {
              chomp;
              ($from, $to) = split / = /;
              $h{$from} = $to;
              last if eof;
          }
          $regex = join "|", map quotemeta, keys %h;
          s/($regex)/$h{$1}/, print while <>
         ' file1 file2

첫 번째 파일을 읽고 각 줄을 분할한 =다음 쌍을 $from => $to해시에 저장합니다. 그런 다음 모든 키(즉, 키가 나온 키)를 기반으로 정규식을 생성하고 두 번째 파일을 반복하여 일치하는 항목을 해시에 저장된 값으로 바꿉니다. 동일한 위치에서 시작하는 두 개의 패턴이 있는 경우 더 긴 문자열을 사용하기 위해 키를 길이별로 정렬하는 것도 일반적입니다.

map quotemeta, sort { length $b <=> length $a } keys %h;

답변2

원래 행 순서를 유지하지 않고 출력을 혼합할 수 있는 경우 다음을 사용할 수 있습니다.가입하다

join -o 2.1,1.2 -2 2 -t':' \
    <(sed 's/^/ /;s/ =/:/' File1 |sort -t: -k1,1)\
    <(sort -t: -k2 File2)

답변3

두 파일(: 대 =)에 대해 서로 다른 구분 기호를 선택하지 않으면 이는 연관 배열을 사용하는 매우 표준적인 찾기 작업이 됩니다.awk

GNU 버전이 있는 경우 awk규칙을 사용하여 파일 사이의 구분 기호를 변경하면 ENDFILE다음을 수행할 수 있습니다.

gawk 'BEGIN{FS=" = "} NR==FNR {a[$1]=$2;next} ENDFILE{FS=": "; OFS=FS;} {print $1, a[$2]}' file1 file2
Trying to figure out: mystringrocks
Still trying to figure it out: mystringrocksmore

관련 정보