Bash 让head显示除最后一行以外的所有文件:命令替换和标准I/O重定向
我一直试图让Bash 让head显示除最后一行以外的所有文件:命令替换和标准I/O重定向,bash,unix,pipe,Bash,Unix,Pipe,我一直试图让head实用程序显示标准输入的最后一行以外的所有内容。我需要的实际代码大致是catmyfile.txt | head-n$($(wc-l)-1))。但那没用。我是在Darwin/OSX上做这件事的,它没有很好的head-n-1语义,这会让我得到类似的输出 这些变体都不起作用 cat myfile.txt | head -n $(wc -l | sed -E -e 's/\s//g') echo "hello" | head -n $(wc -l | sed -E -e 's/\s//
head
实用程序显示标准输入的最后一行以外的所有内容。我需要的实际代码大致是catmyfile.txt | head-n$($(wc-l)-1))
。但那没用。我是在Darwin/OSX上做这件事的,它没有很好的head-n-1
语义,这会让我得到类似的输出
这些变体都不起作用
cat myfile.txt | head -n $(wc -l | sed -E -e 's/\s//g')
echo "hello" | head -n $(wc -l | sed -E -e 's/\s//g')
我测试了更多的变化,特别是发现这是可行的:
cat <<EOF | echo $(($(wc -l)-1))
>Hola
>Raul
>Como Esta
>Bueno?
>EOF
3
这一次给了我一个非法的行计数错误,这是可以理解的。但它至少告诉我,head
程序在将内容传递到subshell/命令替换之前没有使用标准输入,这是一种遥远的可能性,但无论如何我都想排除这种可能性
echo "hello" | head -n $(cat && echo 1)
如何解释
head
和wc
的行为及其通过子shell的交互作用?感谢您的帮助。head-n-1
将提供除最后一行输入之外的所有内容。head
是错误的工具。如果要查看除最后一行以外的所有行,请使用:
sed \$d
原因是
# Sample of incorrect code:
echo "hello" | head -n $(wc -l | sed -E -e 's/\s//g')
失败的原因是wc
消耗了所有输入,并且没有任何内容可供head
查看wc
从运行它的子shell继承其stdin,该子shell从echo
的输出读取数据。一旦它使用了输入,它就会返回,然后head
尝试读取数据……但数据都消失了。如果要读取两次输入,则必须将数据保存在某个位置。使用sed:
sed '$d' filename
将删除文件的最后一行
$ seq 1 10 | sed '$d'
1
2
3
4
5
6
7
8
9
对于这项工作,awk一行程序比sed一行程序长一点
cat myfile.txt | echo $(($(wc -l)-1))
这很有效。这太复杂了:你可以只为MacOSX写
echo$($(wc-l)-1)),具体来说,我从一个
假设您使用的是自制软件,请运行brew install coreutils
,然后使用ghead
命令:
cat myfile.txt | ghead -n -1
或者,相当于:
ghead -n -1 myfile.txt
最后,如果要使用不带g
前缀的命令(例如,head
而不是ghead
),请参阅brew info coreutils
。如果您碰巧使用了支持该语法的head
。不是所有人都这样。谢谢@dunc123。但是我补充了一个说明,我不支持head-n-1
。谢谢@William。我可以使用sed
,但在这个问题上,我特别想了解为什么使用head
的方法不起作用。+1究竟为什么会被否决?sedsed
脚本绝对是正确的、可移植的解决方案,我发现解释中没有任何缺陷。否决票是合理的。当答案是根本没有解决问题的sed
解决方案时,就会出现这种情况。@aerijman\$d
是另一种书写'$d'
的方式。$
处理最后一行,命令d
应用于该行。也就是说,它会删除最后一行。@aerijmansed
不太擅长寻址文件末尾的行。使用gnu head(来自coreutils 8.30),您可以执行head-n-$n
(例如,head-n-5
以查看除最后5行以外的所有行)。与所示的head
解决方案不同,此sed
方法适用于FreeBSD。
cat myfile.txt | head -n $(wc -l | sed -E -e 's/\s//g')
head -n $(($(wc -l <myfile.txt) - 1)) <myfile.txt
sed -n '$! p'
sed '$ d'
cat myfile.txt | ghead -n -1
ghead -n -1 myfile.txt