문제는 전체 명령을 SED와 같은 줄에 넣을 수 없다는 것입니다. 그렇게 했지만 다음 파일에서는 작동하지 않습니다. 내 예:
<file>Documents/time/text1</file> //2X slash + 2 words to remove !!
<file>Commun/text2</file> //1X slash to remove + 1 words to remove
<file>Current/text3</file> //1X slash to remove + 1 words to remove
이 코드가 온라인에서 작동하지 않는 이유는 무엇입니까?
sed 's/Documents//g' | sed 's/time//g' | sed 's/Commun//g' | sed 's/Current//g' | sed 's/Current//g' | sed '/<file>/s|<file>/|<file>|' | sed '/<file>/s|<file>/|<file>|' tracklist.txt > newtracklist.txt
답변1
OP의 현재 스크립트 파이프라인을 실행하면 입력 파일( )의 내용이 stdout으로 인쇄된 다음 파이프라인이 중단 sed
됩니다 tracklist.txt
(즉, 다른 출력이 없거나 명령 프롬프트로 돌아가지 않음). 그래요추측하다OP가 언급할 때 언급한 내용입니다.it does not work
... ??
주요 문제: 입력 파일( )은 마지막 스크립트 가 아닌 첫 번째 스크립트 tracklist.txt
에 대한 인수로 제공되어야 합니다 .sed
sed
추천하다:
# instead of this:
sed 's/Documents//g' | ... | sed '/<file>/s|<file>/|<file>|' tracklist.txt
^^^^^^^^^^^^^
# do this:
sed 's/Documents//g' tracklist.txt | ... | sed '/<file>/s|<file>/|<file>|'
^^^^^^^^^^^^^
sed
OP 파이프라인의 업데이트된 버전을 실행하면 다음이 생성됩니다.
<file>text1</file>
<file>text2</file>
<file>text3</file>
HTML/XML을 구문 분석하기 위한 더 나은 도구가 있지만 OP가 이를 사용해야 하는 경우 sed
더 효율적인 방법으로 동일한 결과를 생성할 수 있는 방법이 있습니다.
아이디어에는 sed
스크립트가 필요합니다.
sed -E 's|(<file>).*/([^/]+</file>)|\1\2|' tracklist.txt
어디:
-E
- 확장 정규식 지원 활성화(<file>)
- (첫 번째 캡처 그룹) 문자열과 일치합니다.<file>
([^/]+</file>)
- (두 번째 캡처 그룹)/
뒤에 문자열이 없는 모든 문자 와 일치합니다.</file>
.*/
- 두 캡처 그룹 사이의 모든 것은/
\1\2
- 대체 문자열은 함께 추가된 두 개의 캡처링 그룹으로 구성됩니다.- 노트:이는 OP에서 제공하는 특정 입력에 대해 작동합니다. 입력이 OP의 예시 입력에 표시된 것과 다른 형식인 경우 조정이 필요할 수 있습니다.
OP의 샘플 입력의 경우 다음이 생성됩니다.
<file>text1</file>
<file>text2</file>
<file>text3</file>
답변2
입력 XML 파일이 주어지면
r
루트 노드 추가 :
<r>
<file>Documents/time/text1</file>
<file>Commun/text2</file>
<file>Current/text3</file>
</r>
암호:
xidel --xquery '
<r>{
for $x in //file
return <file>{tokenize($x, "/")[last()]}</file>
}</r>
' --output-format=xml --output-node-indent file.xml
생산하다:
<?xml version="1.0" encoding="UTF-8"?>
<r>
<file>text1</file>
<file>text2</file>
<file>text3</file>
</r>
설명하다:
여기서는 sed
잘못된 도구를 사용하는 대신 올바른 구문 분석기를 사용하고 있습니다 XPath
( XQuery
전자는 후자의 하위 집합입니다) XML
.
xidel
HTML/XML 작업의 스위스 군용 칼입니다.
용법:
xidel ... file.xml > new_file.xml
편집하고 싶다면비행 중:
xidel ... file.xml | sponge file.xml
sponge
~에서암소 비슷한 일종의 영양 more-utils
.
답변3
사용행복하다(이전 Perl_6)
~$ raku -MXML -e 'my $xml = open-xml( $*ARGFILES.Str );
for $xml.elements( :RECURSE(0), :TAG{"file"} ) -> $E {
my $old = $E.contents[0];
my $new = XML::Text.new( text => $old.text.match(/ <?after "/"> <-[/]>+ $/) );
$E.replace( $old, $new );
}; .say for $xml;' file.xml
또는:
% raku -MXML -e 'my $xml = open-xml( $*ARGFILES.Str );
for $xml.elements( :RECURSE(0), :TAG{"file"} ) -> $E {
my $old = $E.contents[0];
my $new = XML::Text.new( text => $old.text.path.basename );
$E.replace( $old, $new );
}; .say for $xml;' file.xml
Raku는 고급 기능을 갖춘 Perl 제품군의 프로그래밍 언어입니다.문법텍스트를 구문 분석하는 데 사용됩니다. Raku/Rakudo 자체 외에도 커뮤니티 구성원은 Raku/Rakudo 생태계의 모듈을 지원합니다. 이러한 모듈 중 하나는 (라쿠 출신) XML
모듈.
OP의 다른 질문과 유사하게 XML
-module을 사용하는 Raku에서는 (예를 들어) 교체를 1로 제한할 수 있습니다. 최상층 및 2). TAG 내에서만 가능합니다 <file>
. 이는 elements
제약 조건 내에서 반복 하도록 코드를 설정하여 수행됩니다 :RECURSE(0), :TAG{"file"}
. 참고로, TAG
필요한 경우 모든 깊이에서 모든 s를 반복할 수 있습니다. 명명된 인수를 설정 :RECURSE(Inf)
하고 제거하면 제한이 False로 설정됩니다.:TAG
:TAG
위의 첫 번째 대답은 교체에 적합한 태그/수준을 식별합니다. 이는 각 요소의 내부 부분(즉, TAG가 아닌 부분)이 실제로 객체인 contents[0]
변수에 할당되었음을 확인합니다 . 객체를 문자열로 추출하고 원하는 객체를 찾습니다. 이제 수정된 키/값 쌍을 사용하여 새( ) 객체를 생성( )합니다 . 이제부터 -module의 루틴이 작업을 수행합니다.$old
XML::Text
$old
.text
match
XML::Text.new
$new
text => 'value'
XML
replace
replace( $old, $new )
위의 두 번째 답변은 첫 번째 답변을 영리하게 변형한 것입니다. OP는 경로 이름을 편집하려고 하기 때문에 IO::Path
Raku 개체 클래스와 관련된 루틴을 사용할 수 있습니다. Raku의 .IO
루틴은 텍스트를 유효한 경로 이름으로 이해하고 Raku의 .basename
루틴은 최종 파일 이름을 반환합니다. Raku에는 다양한 플랫폼에서 올바른 ( /
또는 \
) 경로 구분 기호를 사용하는 메커니즘이 있으므로 이 접근 방식은 코드 이식성을 향상시킬 수 있는 잠재력이 있습니다.
입력 예(@GillesQuénot에게 감사드립니다!):
<r>
<file>Documents/time/text1</file>
<file>Commun/text2</file>
<file>Current/text3</file>
</r>
예제 출력:
<?xml version="1.0"?><r>
<file>text1</file>
<file>text2</file>
<file>text3</file>
</r>
https://github.com/raku-community-modules/XML
https://docs.raku.org/type/IO/Path
https://rakudo.org/
https://raku.org