xargs -I {}에서 개행 문자를 유지하는 방법

xargs -I {}에서 개행 문자를 유지하는 방법

다음은 수십 줄을 변수로 추출하지만 어떻게든 모두 한 줄에 함께 배치됩니다. 즉, 원래 개행 문자를 잃습니다.

ALL_FOUND_LINES=$(find "$TEMP" -type f -name "debug.log*" | xargs -I {} grep -F "STARTING HOST " {})

위와 같은 명령문에서 개행 문자를 유지하는 방법이 있습니까?

답변1

이것을 테스트하는 경우

echo $ALL_FOUND_LINES

$ALL_FOUND_LINES그런 다음 쉘이 공백, 탭 및 줄 바꿈(기본적으로)의 값을 단어로 분할하고 파일 이름 생성(globbing)을 통해 각 단어를 추가로 확장하므로 모든 줄 바꿈이 사라진 것에 놀라지 않습니다 . 확장이 인용되지 않았기 때문에 이 작업을 수행합니다. 그런 다음 유틸리티 echo는 한 줄에 인쇄되는 단어 목록을 가져옵니다.

더 나은 테스트는

printf '%s\n' "$ALL_FOUND_LINES"

변수 확장을 인용한 것을 참고하세요. printf이상 선택에 대해서는 echo다음을 참조하세요.왜 printf가 echo보다 나은가요?.


귀하의 명령은 다음과 같이 향상될 수 있습니다.

find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} +

여기서는 파일 이름을 에 전달하는 대신 한 번에 최대한 많은 파일을 직접 실행하도록 xargs합니다 . 이 문제와 아무 관련이 없으므로 제거해도 개행 문제가 해결되지는 않습니다 . .​findgrepdebug.log*xargsxargsgrep

또한보십시오`find`의 -exec 옵션 이해.

발견된 각 줄에 대해 뭔가를 수행해야 하는 경우 다음과 같이 반복할 수 있습니다.

find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} + |
while IFS= read -r line; do
    # use "$line" here (with quotes)
done

(또는 수행해야 하는 다른 처리 단계로 while 루프를 교체합니다.) 따라서 변수의 모든 데이터를 개행으로 구분된 문자열로 저장할 필요가 없습니다.

또한보십시오"IFS= 읽기 -r 라인" 이해

답변2

남자 xargs

   -L max-lines
          Use at most max-lines nonblank input  lines  per  command  line.
          Trailing blanks cause an input line to be logically continued on
          the next input line.  Implies -x.

   -l[max-lines], --max-lines[=max-lines]
          Synonym for the -L option.  Unlike -L, the max-lines argument is
          optional.   If  max-lines  is not specified, it defaults to one.
          The -l option is deprecated since the POSIX  standard  specifies
          -L instead.

관련 정보