이중 괄호 값 찾기 및 바꾸기

이중 괄호 값 찾기 및 바꾸기

[[KEY]]HTML 파일 중 하나의 이중 괄호를 VALUE다른 파일에서 사용할 수 있는 .키 값으로 바꿔야 합니다 . 교체한 후에는 출력을 별도의 파일에 넣어야 합니다.

따라서 매개변수로 두 개의 입력 파일과 하나의 출력 파일이 있습니다.

HTML 파일: foo.html

<html>
<head>
<title>[[title]]</tittle>
</head>
<body>[[body]]</body>
</html>

속성 파일: foo.properties

title=foo title
body= foo body

결과물 파일

<html>
<head>
<title>foo title</tittle>
</head>
<body>foo body</body>
</html>

매개변수에 모든 파일 이름을 전달하여 bash 스크립트를 만드는 방법은 무엇입니까?

답변1

그리고 sed:

sed -f <(sed 's/\(.*\)=\(.*\)/s\/\\[\\[\1\\]\\]\/\2\//' foo.properties) foo.html

내부 호출은 검색 및 대체 쌍을 구성한 다음 외부 sed(스크립트 파일)에서 읽습니다 sed.-f

다음과 같이 sed파일에서 명령을 생성합니다 .foo.properties

s/\[\[name\]\]/replace string/

이것들은 두 번째 파일에 대해 읽고 실행됩니다 foo.html.

답변2

Eric Renouf의 말이 맞습니다. bash가 최고의 도구는 아닐 수도 있지만 그렇다고 해서 제가 시도하는 것을 막지는 못했습니다!

다음 스크립트는 여러 bash-isms를 사용하여 작업을 수행합니다.

  1. mapfile입력 파일 읽기(기본 배열 MAPFILE로), 후행 개행 문자 자르기( -t)

  2. [[키=값 쌍처럼 보이는 번역 파일에서 행을 찾는 것이 유일한 목적인 내장 조건식 입니다. 정규식은 키에 대해 최소한 하나의 문자와 값에 대해 하나의 문자를 볼 것으로 예상합니다.

  3. expr그런 다음 sed 표현식으로 사용할 변수를 생성합니다 .

배시 스크립트:

#!/usr/bin/env bash

# Usage: $0 [input file] [translation file] [output file]

mapfile -t < "$2"
expr=""
for keyvalue in "${MAPFILE[@]}"
do
  if [[ $keyvalue =~ (.+)=(.+) ]]
  then
     k="${BASH_REMATCH[1]}"
     v="${BASH_REMATCH[2]}"
     expr="$expr s/\[\[$k\]\]/$v/g;"
  fi
done
sed "$expr" "$1" > "$3"

초점을 맞추면 입력 파일에서 mapfile을 다시 사용하고 MAPFILE 변환 배열을 반복하고 ${parameter/pattern/string}각 입력 줄에서 확장을 사용하여 새 출력 파일을 작성합니다. 나중에!

용법:scriptname foo.html foo.properties outputfoo.html

OP의 예제 입력 파일에서 실행하면 outputfoo.html에는 다음이 포함됩니다.

<html>
<head>
<title>foo title</tittle>
</head>
<body> foo body</body>
</html>

..."foo body"의 선행 공간을 포함합니다!

나중에 일어난 일

나는 궁금해서 위의 bash 버전을 더 생각해 냈습니다. sed를 사용하지 않지만 입력 파일을 반복하는 동안 각 대체에 대해 bash의 인수 확장을 사용합니다.

#!/usr/bin/env bash

# Usage: $0 [input file] [translation file] [output file]

mapfile -t < "$2"
declare -A replacements
for keyvalue in "${MAPFILE[@]}"
do
  if [[ $keyvalue =~ (.+)=(.+) ]]
  then
     k="${BASH_REMATCH[1]}"
     v="${BASH_REMATCH[2]}"
     replacements[$k]="$v"
  fi
done

mapfile -t < "$1"
for line in "${MAPFILE[@]}"
do
  for pattern in "${!replacements[@]}"
  do
    line="${line//\[\[$pattern\]\]/${replacements[$pattern]}}"
  done
  printf "%s\n" "$line"
done > "$3"

관련 정보