날짜와 같은 변수가 포함된 텍스트 파일에 일부 선택 문을 저장하고 싶습니다.
$ cat res.txt
select field1, field2 from log and log_time~'"${TODAY}"*'
스크립트를 사용하여 파일을 구문 분석하고 각 명령문에 대해 실행하고 싶습니다. 물론 ${TODAY}
변수로 대체됩니다.
불행히도 ${TODAY}
파일을 읽을 때 날짜로 대체되지 않습니다 ...
이것을 달성할 수 있는 방법이 있나요?
고쳐 쓰다:
일부 SQL 문이 포함된 파일을 반복하고 psql(postgres)을 사용하여 실행하고 싶다고 가정해 보겠습니다.
파일은 다음과 같습니다.
$cat sql.res
select path from log where log_host='toto' and log_time~'"${TODAY}"*' and log_msg='POLICY MISSING' and entry_status!='ACK' and path~'^/logs-${cli}/"${THREE_MONTHS_AGO}"_[0-9][0-9][0-9][0-9][0-9][0-9](_[0-9]{1,2}\.|\.)log(ptr|initial_ptr|account_ptr)?\.bz2$';
이제 bash 스크립트에서 다음을 수행하고 싶습니다.
$cat script.sh
TODAY=$(date "+%Y-%m-%d")
THREE_MONTHS_AGO=$(date -d "$TODAY -91 days" "+%Y-%m-%d")
THREE_MONTHS_AGO_2=$(date -d "$TODAY -92 days" "+%Y-%m-%d")
ONE_MONTH_AGO=$(date -d "$TODAY -36 days" "+%Y-%m-%d")
ONE_MONTH_AGO_2=$(date -d "$TODAY -37 days" "+%Y-%m-%d")
YESTERDAY=$(date -d "$TODAY -1 day" "+%Y-%m-%d")
while read item; do
psql -P pager=off -t -c "$item" log | sed -e 's|^ *||' -e '/^$/d' > result.txt
done < sql.res
불행하게도 이러한 변수는 스크립트에서 사용되지 않습니다. 그래서 평가를 해보았습니다. 나는 이것을 가지고있다:
$while read item; do
c=$(echo $item | sed "s:':@:g" | sed "s:|:EE:g" | sed "s:(:AA:g" | sed "s:):BB:g" | sed 's:]{:TT:g' | sed 's|\.|OO|g')
b=$(eval echo ${c} 2>&1)
d=$(echo $b | sed "s:@:':g" | sed "s:EE:|:g" | sed "s:AA:(:g" | sed "s:BB:):g" | sed 's:TT:]{:g' | sed 's:OO:\\\.:g' )
echo "-> $b"
done < sql.res
하지만 몇 가지 질문이 있어요
\.
답변1
간단히 문자열 변수를 다음 값으로 바꿀 수 있습니다.
sed -e "s/\${TODAY}/$TODAY/g" res.txt
하지만:
- 신뢰할 수 있는 수단(예: 제공된 데이터베이스 또는 널리 사용되는 프로그래밍 언어 API의 일부로 생성)을 통해 변수를 실행했는지 반드시 확인하십시오.아니요집에서 만든 물건)탈출 메커니즘.
- 또한 모든 문자를 이스케이프해야 합니다.특정
sed
(그리고 각 문자 앞에 백슬래시를 추가할 수는 없습니다.) - 두 가지 수준의 따옴표를 사용하고 있는데 이는 아마도 원하는 것이 아닐 것입니다.
- 이를 위해서는 Bash보다 더 나은 언어를 사용하십시오. 모든 인용 및 이스케이프 비즈니스가 상황을 복잡하게 만들기 때문에 이런 종류의 일은 끔찍합니다.진짜특별한 상황을 놓치기 쉽습니다. Python, Ruby, 심지어 PHP도 Bash보다 이런 종류의 작업을 훨씬 더 잘 처리합니다.