다음 형식의 여러 항목이 포함된 소스 파일이 있습니다.
some_id: some string
.txt
ID로 식별되는 문자열을 포함하는 여러 폴더에 있는 여러 파일
id="some_id"
소스 파일 중 하나와 일치하는 .txt
파일의 모든 문자열이 다음과 같은 새 매개 변수를 추가 하도록 소스 파일을 구문 분석하려면 어떻게 해야 합니까?id
id="some_id" some_param="some string"
해당 소스 파일 ID에서 가져온 값
노트
- 동일한 파일에 여러 ID가 있을 수 있습니다.
- 어떤 파일에도 중복된 ID가 표시되지 않습니다.
- 그들은 결코 같은 줄에 있지 않습니다
some_param
문자 그대로의 의미이다some_param="string"
같은 줄에 간격을 두고 새 콘텐츠를 추가하는 위치는 중요하지 않습니다.
일부 샘플
소스 파일.yml
apples: Apples are very tasty
grapes: Grapes kind of ok
trees: Gain mass from CO2
strawberry: Yummy
과일/foo.txt
This is some plain text
Toreplace id="apples" string contains
The most vitamin-rich berry is id="strawberry"
과일/이상한/포도.txt
And id="grapes" the
문제/trees.txt
Or id="tress"
이 예에서 스크립트는 다음과 같아야 합니다.과일/foo.txt입력하다:
This is some plain text
Toreplace id="apples" string contains some_param="Apples are very tasty"
The most vitamin-rich berry is id="strawberry" some_param="Yummy"
답변1
복잡한Grep
+GNUAwk
해결책:
주요 awk
스크립트 내용은 다음과 같습니다 add_param_by_id.awk
.
#!/bin/awk -f
BEGIN{ FS=":[[:space:]]+" }
NR==FNR{ a[$1] = $2; next }
match($0, /\<id="([^"]+)"/, b) && b[1] in a{
sub(/\<id="[^"]+"/, "& some_param=\042"a[b[1]]"\042")
}1
주요 명령:
export pat="($(cut -d':' -f1 source.yml | paste -s -d'|'))"
grep -ElZr "\<id=\"$pat\"" --include=*.txt | xargs -0 -I{} sh -c \
'awk -f add_param_by_id.awk source.yml "$1" > "/tmp/$$" && mv "/tmp/$$" "$1"' _ {}
pat
- 식별자가 포함된 교대로 정규 표현식 그룹을 포함하는 변수입니다.(apples|grapes|trees|strawberry)
grep -ElZr id=\"$pat\" --include=*.txt
- 지정된 식별자와 일치하는 모든 파일 이름을 인쇄합니다.
처리된 샘플 파일 콘텐츠:
This is some plain text
Toreplace string contains id="apples" some_param="Apples are very tasty"
The most vitamin-rich berry is id="strawberry" some_param="Yummy"
답변2
"파일 이름에 이상한 문자가 없습니다" 및 "데이터 값과 일치하거나 바꾸는 문자가 없습니다"와 같은 특정 경고가 표시되면 /
이 방법이 도움이 될 것입니다. YAML 파일의 각 줄에서 찾을 수 있는 모든 파일을 반복하므로 그다지 효율적이지 않지만, 이 문제를 해결하려면 YAML 파일의 상대적 크기와 대상 파일 수에 대한 추가 정보가 필요합니다.
while IFS=: read -r id sp
do
id="id=\"$id\"" sp="some_param=\"${sp:1}\""
find . -type f -name '*.txt' |
while IFS= read -r file
do
sed -i "/\<$id/s/$/ $sp/" "$file"
done
done <source.yml