이 xargs 다중 명령에서 괄호를 처리합니다.

이 xargs 다중 명령에서 괄호를 처리합니다.

다음 질문에 이미 답변이 있는 것 같지만 질문의 용어를 모르고 기존 답변을 찾을 만큼 충분합니다.

나는 파일 목록을 반복하고 각 줄에 파일 이름과 P로 시작하는 줄 수를 출력하는 명령을 작성하고 있습니다. 지금까지 나는 다음을 가지고 있습니다 :

find -type f | xargs -I % sh -c '{ echo %; grep -P "^P \d+" % | wc -l; }  | tr "\n" ","; echo ""; '

(실제 find 명령은 좀 더 복잡하지만 간단히 말해서 이 명령을 실행한 디렉토리 트리에서 약 11,000개의 관심 파일을 찾았습니다.)

이 명령은 내 목적에 대해 약 98% 작동하지만 이름에 대괄호가 있는 파일의 소수가 있다는 것을 발견했으며 이를 무시하거나 대괄호를 다른 것으로 영구적으로 바꿀 수 없습니다.

그 결과 다음과 같은 사례를 받았습니다.

sh: -c: line 0: syntax error near unexpected token `('

괄호는 쉘 특수 문자라는 것을 알고 있습니다. 예를 들어 이름에 괄호가 있는 단일 파일에 대해 grep을 직접 실행하는 경우 파일 이름을 작은따옴표로 묶거나 괄호를 이스케이프해야 합니다. grep 호출에서 작은 따옴표 안에 "%"를 넣을 수 있도록 명령에서 따옴표 유형(가장 바깥쪽 큰 따옴표, 내부 작은 따옴표)을 바꾸려고 시도했지만 도움이 되지 않았습니다.

find -> xargs -> shsh 호출에서 괄호가 올바르게 처리되도록 체인의 괄호를 처리하는 방법이 있습니까 ?

답변1

데이터(파일 이름)를 코드(셸 스크립틀릿)에 직접 포함하지 않는 것이 가장 좋습니다. 대신, xargs실행하는 셸 에 파일 이름을 인수로 전달하세요 .

find -type f | xargs -I % \
  sh -c '{ echo "$1"; grep -c -P "^P \d+" "$1"; } | tr "\n" ","; echo' sh %

grep -c또한 대신 을 사용할 수 있어야 합니다 grep | wc -l. 그러면 최소한 명령이 조금 더 짧아집니다.

답변2

.에서 생략했으므로 GNU인 find . -type f것 같습니다 . 그러면 다음을 수행할 수 있습니다.findfind

find . -type f -printf %p, -exec grep -cP '^P \d' {} ';'

파일 경로에 :문자가 포함되어 있지 않으면 다음을 수행할 수도 있습니다(GNU 사용 grep).

grep -rcP '^P \d' . | tr : ,

:문자가 포함되어 있지만 개행 문자는 포함되어 있지 않은 경우 :줄의 마지막 문자만 바꾸면 이 문제를 해결할 수 있습니다 ,.

grep -rcP '^P \d' . | LC_ALL=C sed 's/\(.*\):/\1,/'

이 방법은 다음 용도로도 사용할 수 있습니다.

find ... -type f -exec grep -cHP '^P \d' {} + | ...

find예를 들어 더 많은 선택 기준이 있기 때문에 여전히 를 사용해야 하는 경우 .

답변3

일까츄의 대답좋은 개선이 된 것 같고 아마도 무엇을 해야 할지 모르겠습니다.

정보 제공을 위해 더 가벼운 터치 수정을 추가하여 문제가 무엇인지 보여줍니다.

find -type f | xargs -I % sh -c '{ echo "%"; grep -P "^P \d+" "%" | wc -l; }  | tr "\n" ","; echo ""; '

%기본적으로 - 대체될 항목 에 대한 참조입니다 .

관련 정보