Я тренируюсь | трубопровод для передачи вывода.
Во-первых, я пробую использовать командную строку ниже,
$ basename -a $(ls test_directory/*)
Эта строка работает как моя цель, которая показывает только имя файла без имени каталога.
Но следующая команда не сработала.
$ ls test_directory/* | basename -a
Сообщение об ошибке здесь:
basename: missing operand<br>
Try 'basename --help' for more information.
Я нашел такую страницу, относящуюся к моему вопросу.
Передать вывод предыдущей команды следующей в качестве аргумента
1.Передача ввода с помощью стандартного ввода:
ls | wc -l Это будет подсчитывать строки в выводе ls
2. Передача ввода с помощью аргументов командной строки:
wc -l $ (ls) Это будет подсчитывать строки в списке файлов, напечатанных ls
Я не могу понять разницу между "выводом ls" и "файлами, напечатанными ls". Разве это не одно и то же? Я хочу понять разницу.
И я хочу понять, почему моя пробная командная строка "$ ls td / * | basename -a" не работает.
Хотел бы я получить совет.
Спасибо за чтение.
Чтобы объяснить разницу между ls | wc -l
и wc -l $ (ls)
. Приведу пример.
Например, у меня есть каталог ~ / Desktop / Practice / python
, который содержит 4 сценария Python.
Теперь, если я использую указанную выше команду, я получаю следующий результат:
4
Это означает, что wc -l
подсчитывает вывод команды ls
, которая вернула 4 сценария Python, следовательно count стало 4
Теперь, если я использую указанную выше команду в том же каталоге, я получаю следующий результат:
12 palindrome1.py
11 palindrome2.py
12 palindrome3.py
6 palindrome4.py
Всего 41
Это показывает, что wc -l
на этот раз подсчитал количество строк, присутствующих в каждом отдельном скрипте Python, который был возвращен ему ls
.
В вашем случае это было базовое имя
. Если вы читаете справочную страницу basename:
NAME
basename - strip directory and suffix from filenames
SYNOPSIS
basename NAME [SUFFIX]
basename OPTION... NAME...
DESCRIPTION
Print NAME with any leading directory components removed. If specified, also remove a trailing SUFFIX.
Mandatory arguments to long options are mandatory for short options too.
-a, --multiple
support multiple arguments and treat each as a NAME
Здесь четко указано, что basename
принимает аргументы командной строки для ввода. Следовательно, труба не будет работать.
ls | xargs basename -a
Это работает, потому что xargs
принимает стандартный ввод и передает другой команде как «аргумент командной строки».
Надеюсь, это проясняет ваш вопрос.
Самый простой способ продемонстрировать это:
Некоторые команды созданы для приема stdin
. Возьмем для примера кот
. Вы можете направить вывод команды предварительного просмотра на cat
:
$ echo hi | cat
Некоторые команды получают только аргументы в качестве входных данных, например echo
. Если вы запустите:
$ ls | echo
, он направит вывод ls
в echo
. Но echo
его не получит. Чтобы использовать echo
, вы должны указать ему несколько аргументов:
$ echo "I'm an argument"
Если вам нужно использовать вывод команды в качестве аргумента для какой-либо другой команды (например, в случае, когда она принимает только аргументы, а не ] stdin
), у вас есть разные варианты. Один из них - использовать подстановку команд:
$ echo $(ls)
В этом случае ls
будет запущен, тогда вывод ls
будет передан в качестве аргументов echo
.
То же самое для basename
. Вы должны передавать аргументы.
Также есть команды, которые могут принимать аргумент и stdin
одновременно. Например кот
. Если вы отправите что-то в cat
, он распечатает это. Однако для аргумента необходимо передать имя файла
, чтобы распечатать его содержимое.