"ls | wc -l"이 현재 디렉터리의 올바른 파일 수를 표시하는 이유는 무엇입니까? [복사]

"ls | wc -l"이 현재 디렉터리의 올바른 파일 수를 표시하는 이유는 무엇입니까? [복사]

현재 디렉토리의 파일 수를 세려고 시도한 결과 ls -1 | wc -l다음과 같은 의미를 발견했습니다. 파일 목록(각 파일 이름이 새 줄에 인쇄됨)을 wc의 입력으로 보냅니다. 여기서 -l입력 줄 수가 계산됩니다. . 이것은 의미가 있습니다.

나는 그냥 시도해보기로 결정했고 ls | wc -l정확한 수의 파일이 제공되어 매우 놀랐습니다. ls옵션이 없는 명령은 파일 이름을 한 줄에 인쇄하기 때문에 왜 이런 일이 발생하는지 궁금합니다.

답변1

에서 info ls:

'-1'
'--format=단일 열'

한 줄에 하나의 파일을 나열합니다. 이는 표준 출력이 터미널이 아닐 때 "ls"의 기본값입니다.

출력을 파이프하면 ls각 줄에 파일 이름이 부여됩니다.
ls출력이 사람의 눈을 위한 경우에만 열 단위로 파일을 출력합니다.


여기서 ls무엇을 할지 결정합니다:

  switch (ls_mode)
    {
    case LS_MULTI_COL:
      /* This is for the 'dir' program.  */
      format = many_per_line;
      set_quoting_style (NULL, escape_quoting_style);
      break;

    case LS_LONG_FORMAT:
      /* This is for the 'vdir' program.  */
      format = long_format;
      set_quoting_style (NULL, escape_quoting_style);
      break;

    case LS_LS:
      /* This is for the 'ls' program.  */
      if (isatty (STDOUT_FILENO))
        {
          format = many_per_line;
          /* See description of qmark_funny_chars, above.  */
          qmark_funny_chars = true;
        }
      else
        {
          format = one_per_line;
          qmark_funny_chars = false;
        }
      break;

    default:
      abort ();
    }

원천:http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c

답변2

의 출력은 ls표준 출력에 따라 달라지므로 터미널과 파이프의 출력이 다릅니다. 노력하다

/bin/ls | cat

답변3

역사적으로 각 줄은 출력을 파일에 기록했습니다. 이 형식 ls은 . wc그러나 스크롤백 기능이 없는 24라인 터미널에서는 큰 목록이 화면 밖으로 스크롤되는 경향이 있어 원하는 항목을 찾기가 어렵습니다. 그래서 어느 시점에서 BSD 개발자들은변화된 행동따라서 터미널에 인쇄할 때 ls출력 형식은 여러 열로 지정됩니다. 기존 쉘 스크립트가 손상되는 것을 방지하기 위해 파이프나 파일에 쓸 때 이전 동작이 유지됩니다. 그리고 이전 동작은 다음과 같은 명령으로 출력을 처리할 때 더 wc유용 하기 때문입니다. 다중 열 출력을 터미널에 병합 ls하고 이를 터미널의 기본 출력으로 만들기로 한 결정,Rob Pike를 많이 훈련시켰습니다.; Research Unix는 버전 8(BSD를 직접 기반으로 함)까지 새로운 기능을 채택하지 않았으며 Plan 9는 ls스크립트 및 lc대화형 사용을 위한 별도의 명령, lc쉘 스크립트를 통해 호출할 수 있고 다중 열 출력을 제공하는 명령 으로 되돌아갔습니다 ls.mc

-1옵션은 정신을 차리고 적어도 사용자가 출력 대상에 관계없이 특정 출력 형식을 강제하도록 허용하려는 뒤늦은 시도 -C입니다 .ls

답변4

"ls | wc -l"이 현재 디렉터리의 올바른 파일 수를 표시하는 이유는 무엇입니까?

글쎄요, 그건 잘못된 전제입니다. 그렇지 않습니다! 이 시도:

mkdir testdir
cd testdir
# below two lines are one command, the newline is quoted so will be part of argument
echo text | tee "file
name"
ls -l
ls | wc -l

마지막 줄의 출력은 2입니다.

명령으로 콘솔에 인쇄할 때 ls -l,엘에스개행 문자는 있는 그대로 인쇄되지 않고 대신 인쇄됩니다 ?. 그러나 이는 특별히 구현된 함수입니다.엘에스, 재미있는 파일 이름으로 터미널을 복잡하게 만드는 것을 피하기 위해 출력이 실제 터미널로 가는 것을 감지할 때 수행됩니다. 이 동일한 감지는 파일 이름이 한 줄에 하나씩(파이프에서) 인쇄되는지 또는 터미널 너비(분명히 존재하는 경우에만 의미가 있음)를 기준으로 인쇄되는지 여부를 결정합니다.너비가 있는 터미널). 넌 속일 수 있어엘에스ls | cat예를 들어 원래 파일 이름을 줄바꿈으로 구분하여 인쇄하려는 경우 이 명령을 사용하십시오 .

wc -l줄 수만 세고 파일 이름에 개행 문자가 포함되어 있으면화장실두 줄로 처리합니다.


엘에스제어 문자 -q/ 를 강제로 숨기는 스위치도 --hide-control-chars있으므로 ls -q | wc -l에 나열된 정확한 파일 수를 실제로 제공해야 합니다 (대개 스위치가 ls없는 디렉터리의 실제 파일 수와 다름 ). 그 이유는 줄 바꿈만 있기 때문입니다.-a엘에스출력은 파일 이름이 구분된 파일이어야 합니다.

관련 정보