파일에서 발견된 모든 문자열을 다른 파일의 값으로 대체

파일에서 발견된 모든 문자열을 다른 파일의 값으로 대체

data.csv다음과 같은 CSV 파일( )이 있습니다 .

apple_val, balloon_val, cherry_val, dog_val
1         ,5           ,6          ,7
3         ,19          ,2          ,3

sentence.txt다음과 같은 텍스트 파일( )이 있습니다 .

I have apple_val apple(s) and balloon_val balloons. My dog_val dogs were biting the cherry_val cherries. 

output.txt내 출력 파일( )을 다음과 같이 만들고 싶습니다 .

I have 1 apple(s) and 5 balloons. My 7 dogs were biting the 6 cherries.
I have 3 apple(s) and 19 balloons. My 3 dogs were biting the 2 cherries. 

아래 스크립트를 사용했습니다. 하지만 내 스크립트는 위의 예에만 적용됩니다.

awk -F "," {print $1, $2, $3, $4} data.csv | while read a, b, c,d
do
    sed -e "s/apple_val/$a/g" -e "s/balloon_val/$b/g" -e "s/dog_val/$d/g" -e "s/cherry_val/$c/g" sentence.txt >> output.txt
done

CSV 파일의 첫 번째 줄(헤더)을 읽고 텍스트 파일에 있는 이러한 문자열(예: apple_val)을 대체하여 일반 파일로 만들고 싶습니다.

어떻게 해야 합니까?

답변1

수정됨외계인변형(배열 사용):

#!/bin/bash
tr -s ',' ' ' <data.csv | {
read -a tokens
while read -a values; do
    for index in $(seq 0 $((${#tokens[*]}-1))); do
        echo "s/${tokens[$index]}/${values[$index]}/g"
    done | sed -f - sentence.txt
done
}

awk같은

awk -F"[, ]+" '
NR == FNR{
    s=s $0 "\n"
    next}
FNR == 1{
    for(i=1;i<=NF;i++)
        val[i]=$i
    next}
{
    p=s
    for(i=1;i<=NF;i++)
        gsub(val[i], $i, p)
    printf p}
' sentence.txt data.csv

답변2

여기서 하려는 작업을 "템플릿"이라고 하며, 자신만의 템플릿을 수행하는 것은 종종 예상치 못한 함정에 빠지곤 합니다. :)

이것은 요청한 작업을 수행하는 쉘 스크립트이지만 보기에 좋지 않고 매우 취약할 수 있습니다. 보다 강력한 템플릿 솔루션을 찾는 것이 좋습니다.

#!/bin/bash

sentence=$(cat sentence.txt)

tokens=$(head -n1 data.csv | cut -d, -f1- --output-delimiter="")

cat data.csv | tail -n +2 | while read i; do
    token_number=0
    new_sentence=$sentence
    for token in $tokens; do
        let token_number+=1
        value=$(echo $i | cut -d, -f${token_number})
        new_sentence=$(echo $new_sentence | sed -e "s/${token}/${value}/g")
    done
    echo $new_sentence
done

질문에 지정한 입력을 기반으로 한 결과 출력은 다음과 같습니다.

I have 1 apple(s) and 5 balloons. My 7 dogs were biting the 6 cherries.
I have 3 apple(s) and 19 balloons. My 3 dogs were biting the 2 cherries.

관련 정보