포럼의 좋은 사람이 이 스크립트를 만드는 데 도움을 주었지만 내가 던지는 모든 것은 오류를 출력하며 왜, 무엇이 문제인지 전혀 모릅니다. bash test.sh를 요청하면 우분투 터미널에서 모든 스크립트를 실행했습니다.
내 목표는 여러 .xml 파일에 태그를 추가하는 것이지만 process></process>
일부 파일에는 1~100개의 태그가 있을 수 있습니다.
예:
- jfksaJDFH
- <process>value=""</process>
- <process>value=""</process>
- <process>value=""</process>
- <process>value=""</process>
- jdhkjasdh
- <process>value=""</process>
- <process>value=""</process>
- <process>value=""</process>
- <process>value=""</process>
스크립트 이후:
- jfksaJDFH
- <process>value="1"</process>
- <process>value="2"</process>
- <process>value="3"</process>
- <process>value="4"</process>
- jdhkjasdh
- <process>value="5"</process>
- <process>value="6"</process>
- <process>value="7"</process>
- <process>value="8"</process>
스크립트:
#!/bin/bash
dir="/mnt/Desktop/test/"
while IFS= read -r -d '' file
do
i=1
while IFS= read -r -u 3 line
do
if [[ $line = '<process></process>' ]]; then
echo "<process>value=\"$((i++))\"</process>"
else
echo "$line"
fi
done 3< "$file" > "$file.xml"
done < <(find $dir -type f -name \*.xml -print0)
위 스크립트가 실행되면 마지막 스크립트를 제거하십시오.<process>value=""</process>
스크립트를 다음과 같이 수정합니다.
while IFS= read -r -d '' file
do
i=1
while IFS= read -r -u 3 line
do
if [[ $line = '<process></process>' ]]; then
echo "$line"
else
echo "<process>value=\"$((i++))\"</process>"
fi
done 3< "$file" > "$file.xml"
done < <(find $dir -type f -name \*.xml -print0)
파일의 출력은 다음과 같습니다.
<process>value="1"</process>
<process>value="2"</process>
<process>value="3"</process>
<process>value="4"</process>
<process>value="5"</process>
<process>value="6"</process>
<process>value="7"</process>
<process>value="8"</process>
<process>value="9"</process>
<process>value="10"</process>
<process>value="11"</process>
<process>value="12"</process>
<process>value="13"</process>
<process>value="14"</process>
<process>value="15"</process>
<process>value="16"</process>
<process>value="17"</process>
<process>value="18"</process>
<process>value="19"</process>
<process>value="20"</process>
<process>value="21"</process>
<process>value="22"</process>
<process>value="23"</process>
즉, 이는 페이지의 다른 모든 항목을 추가하지만 제거합니다.
답변1
이 스크립트를 파일에 넣으세요(예: 'increase.awk'):
BEGIN { i = 1 }
/.*<process>value=""<\/process>.*/ { split($0, a, "value=\"\"") ; print a[1] "value=\"" i++ "\"" a[2] ; next }
/.*/ { print $0 }
그런 다음 전화하십시오.
gawk -f increase.awk < yourinputfile
설명: awk에서 split("string", a, "separatorstring")
"separatorstring"을 구분 기호로 사용하여 "string"을 a라는 배열로 분할합니다. 따라서 a[1]에는 첫 번째 "구분자 문자열"까지의 모든 내용이 포함되고, a[2]에는 줄 끝이나 다음 "구분자 문자열"까지의 모든 내용이 포함됩니다.
답변2
이 XML을 사용하지 마세요. 원한다면 생각해 보십시오. XML은 공백을 적극적으로 무시하는 구조화된 데이터 유형입니다. eg <attr name="fish" />
및 기타 항목과 같은 단항 태그가 있다는 것은 정규식을 사용하여 한 줄씩 구문 분석하면 언젠가 코드가 이상하게 충돌한다는 것을 의미합니다.
이를 수행하는 방법은 XML 파서를 사용하는 것입니다. 어느 것을 사용할지는 개인 취향의 문제이지만 저는 스크립팅 XML::Twig
(perl 모듈)을 좋아합니다.
설명된 대로 문제를 해결하려면:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
sub increment_value {
my ( $twig, $process ) = @_;
my ($value) = ( $process->text =~ m/(\d+)/ );
print "Got $value\n";
if ( defined ( $value ) ) {
$process->set_text( 'value="' . ++$value . '"' );
}
else {
$process -> delete;
}
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented',
'twig_handlers' => { 'process' => \&increment_value },
);
$twig->parsefile( 'your_file.xml' );
$twig->print; #prints to stdout.
process
이는 텍스트를 추출, 변환 및 대체하는 요소별 "처리기"를 트리거합니다 .
답변3
스크립트를 다시 작성할 때 if-then-else 구문의 논리가 복원되었다는 사실을 알고 계셨습니까?
아래 주석 줄 1과 2의 위치를 확인하세요. 다시 작성된 코드에서 이를 반대로 했습니다.
그리고 IFS=는 -r -d '' 파일을 읽습니다. 하다 나는=1 그리고 IFS= read -r -u 3줄 하다 if [[ $line = '' ]]; echo "value=\"$((i++))\"" # 라인 1****************** 기타 echo "$line" # 2번째 줄******************** 필리핀 제도 3개의 "$file.xml"을 완료하세요. 완벽한