첫째, 내가 cygwin을 사용하고 있다는 사실이 여기서 매우 관련성이 높다고 생각합니다.
이론적으로 나는 이 작업을 수행하는 방법을 이미 알고 있습니다.
cat file | xargs grep pattern
문제는 일부 파일 경로 file
에 공백이 있다는 것입니다. 파일은 다음과 같습니다.
subdir/foo/bar.html
subdir/f o o/ba r.html
subdir/~foo/bar.html
이로 인해 오류가 발생합니다. 이 문제를 해결하는 방법을 읽었습니다. use . 그러나 출력을 null로 끝나는 줄로 xargs -0
만드는 방법을 모르기 때문에 전체 파일을 한 줄로 압축한다는 의미라고 생각했습니다. cat
결과적으로 다음과 같은 오류가 발생합니다.
xargs: argument line too long
고쳐 쓰다:내가 읽고 있던 파일에 더 이상 존재하지 않는 일부 경로가 있는 것으로 나타났습니다. 공교롭게도 이 경로들은 모두 하나씩 있어서 ~
이것이 문제인 줄 착각했습니다. 이 문서는 존재하지 않는 것으로 밝혀졌습니다. 그래도 우주에 관한 모든 것은 남아 있습니다.
답변1
xargs -d '\n'
입력 파일에 한 줄에 하나의 파일 이름이 포함된 경우에 사용됩니다. 예를 들어
xargs -d '\n' grep pattern < file
파일 이름이 "내 홈 디렉토리"로 시작하는 경우 먼저 이 기호를 실제 홈 디렉토리로 바꿔야 ~
합니다 . ~
예를 들어:
sed -e "s=^~=$HOME=" file | xargs -d '\n' grep pattern
이 sed 스크립트는 큰따옴표로 묶여 있습니다.생각하다변수를 $HOME
sed 스크립트에 삽입하고 /s가 포함되므로 이를 연산자의 구분 기호로 사용합니다 ( =
그러나 그럴 가능성은 낮음 ).s
$HOME
=
또는 를 사용하는 경우 xargs 옵션과 함께 find
find 옵션을 사용하세요 . 예를 들어-print0
-0
find ... -print0 | xargs -0 grep pattern
아니면 그냥 find -exec
옵션을 사용하세요:
find ... -exec grep pattern {} +
답변2
다른 답변에서 언급했듯이 xargs -d '\n'
이것이 선호되는 솔루션입니다. (내 생각에는 이것이 바람직하며 이렇게 xargs
해야 합니다.기본, 그러나 그것은 또 다른 이야기입니다. )
그러나 모든 버전이 xargs
지원되는 것은 아닙니다 -d
. 작동하지 않는 방법에 갇혀 있다면 시도해 볼 수 있습니다.
tr '\n' '\0' < file | xargs -0 grep pattern
(옛날에는 tr
이와 같이 null 문자를 대체할 수 없는 버전이 있었지만 오늘날에는 이러한 문자를 접할 가능성이 거의 없습니다.)
답변3
기억하세요: xargs
파일의 전체 내용은 grep에 대한 명령줄 인수로 사용됩니다... 귀하가 받는 오류는 파일에 너무 많은 파일 이름으로 인해 명령줄이 너무 길어서 발생했을 수 있습니다.
콘텐츠가 패턴과 일치하는 파일을 검색하려면 다음과 같은 반복 접근 방식을 사용하는 것이 좋습니다.
gcolangelo@debian-test:/tmp$ cat test_files
/dir1/file1 with space
/dir2/file2 with space
/dir3 with space/file3
gcolangelo@debian-test:/tmp$ while read filepath ; do echo "-- coin ${filepath} --" ; done < test_files
-- coin /dir1/file1 with space --
-- coin /dir2/file2 with space --
-- coin /dir3 with space/file3 --
-- coin --
답변4
어떤 경우에는 while
루프를 사용하는 것이 더 나을 수도 있습니다 xargs
(예: 여러 명령을 실행하려는 경우).
while IFS= read -r file <&3
do
grep -- pattern "$file" 3<&-
done 3< file
grep
그러나 파일당 하나씩 호출한다는 점에 유의하세요.