내가 시도할 때
du -sh $(sed -ne '/\.[hc]$/p' ../all-file)
그것은 말한다
$ bash: /usr/bin/du: Argument list too long
그럼 난 노력해
for i in $(sed -ne '/\.[hc]$/p' ../all-file); do du "$i"; done|vim -
그러나 완료하는 데 오랜 시간이 걸립니다.
소란을 피우지 않고 어떻게 작업 속도를 높일 수 있나요?
답변1
제공된 의견을 토대로 이 사실을 파악하셨나요?
sed -ne '/\.[hc]$/p' ../all-file | xargs du -sh
grep을 사용하지 않는 이유는 무엇입니까? 적어도 두 배는 빠릅니다.
grep '\.[hc]$' ../all-file | xargs du -sh
답변2
GNU 구현을 사용하면 du
다음을 수행할 수 있습니다.
<../all-file LC_ALL=C grep '\.[hc]$' |
tr '\n' '\0' |
du -sh --files0-from=-
GNU를 통해 구현됨 xargs
:
<../all-file LC_ALL=C grep '\.[hc]$' |
xargs -rd '\n' du -sh --
또는 대부분의 BSD에서와 같이 GNU 를 xargs
복사하는 다른 구현을 사용하십시오.-r
-0
-d
<../all-file LC_ALL=C grep '\.[hc]$' |
tr '\n' '\0' |
xargs -r0 du -sh --
그러나 하드 링크의 디스크 사용량은 한 번만 보고되므로 du
목록을 이와 같이 일괄 처리로 분할하면 xargs
결과가 달라질 수 있습니다 . 이 -c
옵션을 사용하여 마지막에 누적된 결과를 얻으려면 이 --files0-from
방법도 사용해야 합니다.
예:
$ seq 100000 > a.c
$ ln a.c b.c
$ du -shc a.c b.c
651K a.c
651K total
b.c
이것이 실제로 와 관련되어 있으므로 이것이 어떻게 보고되지 않는지 확인하십시오 a.c
. 두 파일의 누적 디스크 사용량은 651K입니다.
$ du -shc a.c; du -shc b.c
651K a.c
651K total
651K b.c
651K total
총 651K의 파일 2개를 얻게 되는데, 이는 ac와 bc가 동일한 파일이라는 사실을 숨깁니다.
반면에 하드 링크 처리를 비활성화하고 GNU 구현을 통해 각 파일의 디스크 사용량을 개별적으로 보고하려면 / 옵션을 du
사용할 수 있습니다 . 디스크 사용량보다는 파일 크기에 관심이 있는 경우에도 이 옵션을 참조하세요.-l
--count-links
--apparent-size
최신 버전의 Linux에서는 리소스 제한을 늘려 매개변수 + 환경 크기 제한을 늘릴 수 있습니다 stacksize
.
예를 들어 다음을 사용하면 ulimit -s unlimited
대부분의 쉘( limit stacksize unlimited
zsh에서도 하위 프로세스에서만 작동함)에서 제한을 무시하고 목록 분해를 피할 수 있습니다.
$ /bin/true {1..150000}
zsh: argument list too long: /bin/true
(127)$ limit stacksize unlimited
$ /bin/true {1..150000}
$ /bin/true {1..250000}
$ /bin/true {1..350000}
$ /bin/true {1..500000}
zsh: argument list too long: /bin/true
그런 다음 분할+glob을 사용할 수 있지만 항상 그렇듯이 구분 기호를 줄 바꿈( IFS=$'\n'
)으로 수정하고 아마도 원하지 않는 와일드카드( )를 비활성화 하도록 조정해야 합니다 set -o noglob
.
(
ulimit -s unlimited
IFS=$'\n'
set -o noglob
du -sh -- $(<../all-file LC_ALL=C grep '\.[hc]$')
)
../all-file
이 패턴과 일치하는 줄이 없으면 du
인수 없이 실행하게 되며 기본적으로 현재 작업 디렉터리의 디스크 사용량을 가져옵니다( -r
선택적으로 xargs
이러한 경우를 처리할 수 있음).
추가 참고사항:
sed -ne /re/p
is ( s 에서 파생되었지만 약어grep
입니다 ).grep
ed
g/re/p
- 파일 경로는 NUL이 아닌 바이트로 구성될 수 있으며 임의의 목록을 나타낼 수 있으려면 NUL로 구분하는 것이 확실한 선택이므로
--files0-from
NUL로 구분된 목록이 필요합니다. 이는 개행으로 구분된all-file
파일이 임의의 파일 경로를 나열할 수 없음을 의미합니다. 이는 또한 파일 경로가 텍스트로 구성될 필요가 없기 때문에 텍스트 유틸리티를 사용하여 파일 경로를 처리하는 것이 모든 바이트가 문자인 C와 같은 로케일을 제외하고 작동이 보장되지 않는다는 것을 의미합니다. 를 사용하면LC_ALL=C
바이트를 문자로 디코딩하는 것을 방지하므로 성능이 향상될 수도 있습니다. $(...)
Bash에서 인용되지 않은 버전은 Split+Glob입니다. 파일 경로에 전역 문자나$IFS
변수의 문자가 포함되어 있지 않다는 것을 알고 있는 경우에만 해당 파일 목록을 사용하여 파일 목록을 분할할 수 있습니다.- / 가
xargs
없는 경우 분할은 공백 또는 개행 문자에서 수행되며 작은따옴표/큰따옴표 및 백슬래시는 이스케이프 연산자로 해석됩니다. 즉, 보이는 것처럼 개행으로 구분된 임의의 파일 경로 목록을 처리할 수 없습니다 .-0
-d
all-file
- 변수, 사전에 알려지지 않은 인수 목록을 명령에 전달할 때 첫 번째(또는 GNU 구현이 있는 모든 인수) 인수가 다음 으로
--
끝나도록 하기 위해 옵션 앞에 이 옵션의 끝을 표시 해야 합니다. 명령)은 옵션으로 간주되지 않습니다.-
+