빈 파일을 제외하고 파일을 연결하는 방법은 무엇입니까?

빈 파일을 제외하고 파일을 연결하는 방법은 무엇입니까?

.txt많은 파일을 함께 붙여넣어야 합니다 . 나는 다음 명령을 사용합니다.

cat *.txt > newfile.txt 

일부 파일이 비어 있는 것을 발견했습니다. cat이러한 빈 파일에서 작동하지 않도록 스크립트에 컨트롤을 삽입하려면 어떻게 해야 합니까 ?

감사해요.

답변1

꼭 필요한 것은 아니지만 빈 파일을 제외해야 하는 경우:

for i in *.txt; do [ "$i" != newfile.txt ] && [ -s "$i" ] && cat -- "$i"; done >newfile.txt

-s주어진 파일이 존재하고 비어 있지 않으면 테스트는 참입니다(이것은 표준 테스트입니다. 참조) man test. 또한 출력 파일 자체를 처리하지 않습니다.

답변2

에서는 glob 한정자를 zsh사용할 수 있습니다 .L+0

(cat -- *.txt(n-.L+0)) > newfile.txt

(여기서도 한정적으로정기적인심볼릭 링크 해석() 후에 파일( .)만 결정(및 크기)되며 -파일 목록은 다음과 같이 숫자( n) 로 정렬됩니다.file10.txt뒤쪽에 file9.txt예를 들어).

일반적으로 빈 파일은 출력을 생성하지 않으므로 빈 파일을 포함해도 아무런 효과가 없습니다 cat. 그러나 이를 좋은 생각으로 만드는 두 가지 사항이 있습니다.

  1. newfile.txt에 전달할 파일 목록에 자신을 포함시키고 싶지 않습니다 cat. cat일부 구현에서는 입력 파일이 stdout과 동일한 위치에 있으면 불만을 표시합니다. 이렇게 하지 않으면 마치 cat루프에서 출력 파일을 읽는 것처럼 디스크가 가득 차게 될 수 있습니다. 여기서 리디렉션을 수행한 후 glob이 확장됩니다. 이 리디렉션은 glob이 확장될 때 크기가 0이 되도록 출력 파일을 자릅니다.
  2. 에 전달된 인수 목록에서 불필요한 파일을 제거함으로써 cat명령줄을 더 짧게 만들어 크기 제한에 도달할 가능성을 줄입니다. 하지만 여기서는 zsh'를 사용하여 이 문제를 해결할 수도 있습니다 zargs.

아니요 zsh. 하지만 GNU 유틸리티가 있으면 다음을 수행할 수 있습니다.

 LC_ALL=C find -L . -maxdepth 1 -name '*.txt' ! -name '.*' \
                    ! -name newfile.txt -type f -size +0 -print0 |
   sort -V0 |
   xargs -r0 cat > newfile.txt

-size +0여기에서는 현재 디렉터리에 많은 파일이 있는 것처럼 신뢰할 수 없습니다. xargs결국 검사를 받게 될 수도 있습니다(여기에서도 동시에 실행되므로 시작 및 검사 시 리디렉션이 실행되지 않았을 수 있습니다). 크기가 미리 존재하는 경우).catfindnewfile.txtxargs > newfile.txtfindfindnewfile.txt

find또한 숨겨진 파일은 기본적으로 제외되지 않으므로 수동으로 제외해야 합니다 . 우리는 또한 GNU 의 비문자 문제도 LC_ALL=C해결 해야 합니다 . find이 경우 xargs명령줄 크기 제한이 해결됩니다.

이 방법과 동등한 방법은 다음 zsh과 같습니다.

  • -L-
  • -type f.
  • -size +0L+0
  • sort -Vn

답변3

기존 UNIX 파일 시스템에서와 마찬가지로 빈 파일을 읽는 오버헤드는 파일이 비어 있음을 감지하는 오버헤드와 거의 동일하므로 특히 -ing을 수행할 때 빈 파일만 처리하는 것은 거의 의미가 없습니다 cat.

또한 파일이 순서대로 있어야 하는지 여부도 언급하지 않았습니다. 그렇지 않다면 (어쩌면 find가 여기에서 순서를 보존할 수도 있음), 이것이 다음보다 나을 수도 있습니다.https://unix.stackexchange.com/a/633734/320598:

(find *.txt \! -size 0 | xargs cat) >newfile.txt

관련 정보