많은 수의 XML 파일을 다시 포맷합니다.

많은 수의 XML 파일을 다시 포맷합니다.

저는 중첩된 디렉터리 구조에 흩어져 있는 수많은 XML 파일을 사용하여 작업하고 있습니다.

나는 다음을 시도했다:

$ find . -name "*.xml" -type f | xargs -- xmllint --format

문제는 화면에 형식화된 XML 출력을 생성하지만 파일을 변경하지 않는다는 것입니다.

실제 파일 내용을 변경하도록 이 명령을 어떻게 변경할 수 있습니까?

답변1

find이는 다음을 직접 사용하여 수행할 수 있습니다 -exec.

find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;

전달된 내용은 -exec발견된 각 파일에 대해 한 번씩 호출되어 {}템플릿 매개변수를 현재 파일 이름으로 바꿉니다. \;명령 끝에서 find를 사용하면 해당 줄이 종료됩니다.

xargsxmllint이 경우 입력 및 출력 파일 이름이 동일한 호출에서 지정되어야 하므로 각 파일에 대해 한 번 호출 해야 하므로 실제로 사용할 필요가 없습니다 .

xargsfind에서 전달된 명령이 한 번에 여러 파일을 처리하고 목록이 긴 경우에 필요합니다. 이 경우 단일 파일 이름을 --output에 전달해야 하기 때문에 그렇게 할 수 없습니다 xmllint. 그렇게 하지 않으면 xargs많은 수의 파일을 처리하는 경우 "인수 목록이 너무 깁니다" 오류가 발생할 수 있습니다. 다음 옵션을 사용하는 파일 교체 문자열 xargs도 지원됩니다 .-I

find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'

find -exec위의 명령과 동일한 작업을 수행합니다 . 폴더 중 유사한 공간에 홀수 문자가 포함되어 있는 경우 및 옵션을 사용해야 합니다 -0. 그러나 with를 사용하면 이 옵션은 한 번에 하나의 파일만 처리할 수 있으므로 with를 직접 사용할 수도 있다는 의미입니다.findxargsxargs-I-L 1find-exec

답변2

나는 보통 여러 층의 간접적인 방법을 통해 이러한 문제를 해결합니다. 원하는 작업을 수행하는 쉘 스크립트를 작성한 다음 호출하십시오. 시작으로 추천합니다

#! /bin/sh
for file
do
   xmllint --format $file > $file.tmp && mv $file.tmp $file
done

하나 또는 두 개의 파일에 대해 수동으로 시도한 다음 xargs에서 바꿀 수 있습니다.

find . -name "*.xml" -type f | xargs -- xmltidy.sh

관련 정보