Почему «ls | wc -l "показать правильное количество файлов в текущем каталоге?

Попытка подсчитать количество файлов в текущем каталоге, я нашел ls -1 | wc -l ls -1 | wc -l , что означает: отправить список файлов (где каждое имя файла печатается в новой строке) на вход wc, где -l будет подсчитывать количество строк на входе. Это имеет смысл.

Я решил попробовать просто ls | wc -l ls | wc -l и был очень удивлен, что это также дает мне правильное количество файлов. Интересно, почему это происходит, потому что команда ls без параметров печатает имена файлов в одной строке.

  • Список (или перемещение) только файлов с определенным количеством строк?
  • Выберите файл на основе количества строк и обработайте результат
  • Как создать переменную из данных по каналам
  • wc - установка конечного символа
  • Как эффективно разделить большой текстовый файл без разделения многострочных записей?
  • Использование ls с командой wc
  • Считать ТОЛЬКО алфавитно-цифровые слова в определенном столбце файла
  • Как считать события фразы в grep, игнорируя случай?
  • 4 Solutions collect form web for “Почему «ls | wc -l "показать правильное количество файлов в текущем каталоге?”

    Из 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

    Поскольку выход ls зависит от выхода std, он отличается для терминала и трубы. Пытаться

     /bin/ls | cat 

    Исторически, ls написал свой вывод по одному файлу на строку, что является удобным форматом для обработки с помощью других текстовых инструментов Unix (например, wc ). Однако на 24-строчном терминале без прокрутки большие списки имели тенденцию прокручивать экран, что затрудняло поиск того, что вы искали. Итак, в какой-то момент разработчики BSD изменили поведение, поэтому при печати на терминал ls форматирует свой вывод в нескольких столбцах. Старое поведение сохранялось при записи в канал или файл, чтобы избежать нарушения существующих сценариев оболочки — и потому, что старое поведение более полезно при обработке вывода командой wc . Решения о включении вывода из нескольких столбцов в ls и сделать его дефолтом на терминале, выполняли Rob Pike совсем немного ; Research Unix не подобрал новые функции до 8-го выпуска (который был основан непосредственно на BSD), а Plan 9 вернулся к отдельным командам, ls для скриптов и lc для интерактивного использования, с lc сценарием оболочки, вызывающим ls и командой mc обеспечивающей многоколоночный выход.

    Параметры -1 и -C для ls являются запоздалой попыткой восстановить здравомыслие, по крайней мере, позволяя пользователю принудительно форматировать определенный выходной формат независимо от назначения вывода.

    Почему «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 не будет печатать новую строку как есть, но вместо этого будет печатать ? , Но это специально реализованная функция ls , она делает это, когда обнаруживает, что выход идет на фактический терминал, чтобы избежать смешных имен файлов от возиться с терминалом. Это же обнаружение определяет, будут ли имена файлов печататься по одной строке (в трубе) или по ширине терминала (что, очевидно, имеет смысл только в том случае, если имеется терминал с шириной). Вы можете обмануть команду ls | cat как ls | cat ls | cat если вы хотите напечатать необработанные имена файлов, разделенные символами новой строки.

    wc -l просто подсчитывает количество строк, а если имя файла содержит новую строку, то wc будет считать это двумя строками.


    ls также имеет переключатели для принудительного скрытия управляющих символов, -q / --hide-control-chars , поэтому ls -q | wc -l ls -q | wc -l должен фактически предоставить точное количество файлов, перечисленных в ls (что обычно не совпадает с фактическим количеством файлов в каталоге, без ключа -a ), потому что тогда только новые строки в выводе ls должны быть теми, которые разделяют имена файлов.

    Linux и Unix - лучшая ОС в мире.