我正在练习|
管道传递输出。
首先,我basename
尝试
$ basename -a $(ls test_directory/*)
此行按预期工作,仅显示文件的名称,而不显示目录的名称。
但是当我尝试将输出传输ls
到basename
$ ls test_directory/* | basename -a
错误信息在这里:
basename: missing operand
Try 'basename --help' for more information.
我发现将上一个命令的输出作为参数传递给下一个命令在Unix 和 Linux在该答案之一提及:
通过 stdin 传递输入:
ls | wc -l
这将计算 ls 输出中的行数
通过命令行参数传递输入:
wc -l $(ls)
这将计算 ls 打印的文件列表中的行数
我不明白“ 的输出ls
”和“ 打印的文件ls
”之间的区别。它们不是一回事吗?我想了解其中的区别。
我想了解为什么ls td/* | basename -a
没有起作用。
答案1
ls | wc -l
为了解释和之间的区别wc -l $(ls)
。我将举一个例子。
1.ls | wc -l
正如文章中所提到的,该命令将计算“ls”输出中的行数。
例如,我有一个~/Desktop/Practice/python
包含 4 个 Python 脚本的目录。
现在,如果我使用上述命令,我将获得以下输出:
4
这意味着wc -l
输出的计数ls
返回了 4 个 Python 脚本,因此计数变为 4
2.wc -l $(ls)
再次如帖子所建议的那样,此命令将计算“ls”打印的文件列表中的行数。因为在这种情况下,您将“ls”作为参数传递给命令
现在,如果我在同一目录中使用上述命令,我会得到以下输出:
12 palindrome1.py
11 palindrome2.py
12 palindrome3.py
6 palindrome4.py
41 total
这表明wc -l
这次计算了返回给它的每个单独的 Python 脚本中的行数ls
。
命令行参数和标准输入的区别
实际的区别在于命令的来源。命令可以使用“命令行参数”或“标准输入”来获取输入。因此,如何获取特定命令的输入取决于命令的开发人员。管道将一个命令的标准输出作为标准输入传递给第二个命令。因此,如果第二个命令无法处理标准输入,它将抛出错误。但是,有些命令同时接受命令行参数和标准输入,如“wc”,但结果不同,因为wc
处理标准输入和命令行参数的方式不同。
在你的情况下是这样的basename
。如果你阅读 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
使用命令行参数作为输入。因此管道将不起作用。
如何使管道工作
作为由@bac0n 建议,要执行basename
with 管道,您需要使用xargs
。
ls | xargs basename -a
这是因为xargs
它采用标准输入并将其作为“命令行参数”传递给另一个命令。
答案2
我可以证明这一点的最简单的方法:
一些命令被设计用来接受stdin
。 举cat
个例子。 你可以将 previews 命令的输出通过管道传输到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
。如果你将某些内容通过管道传递给cat
它,它会将其打印出来。但是对于参数,除非你传递一个,否则它filename
会将其内容打印出来。