다음은 수십 줄을 변수로 추출하지만 어떻게든 모두 한 줄에 함께 배치됩니다. 즉, 원래 개행 문자를 잃습니다.
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
합니다 . 이 문제와 아무 관련이 없으므로 제거해도 개행 문제가 해결되지는 않습니다 . .find
grep
debug.log*
xargs
xargs
grep
또한보십시오`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.