如何使用 shell 命令仅显示文本文件中的第一列和最后一列?

如何使用 shell 命令仅显示文本文件中的第一列和最后一列?

我需要一些帮助来弄清楚如何使用 sed 命令仅显示文本文件中的第一列和最后一列。这是我目前为止第一栏的内容:

cat logfile | sed 's/\|/ /'|awk '{print $1}'

我试图让最后一栏也显示出来的无力尝试是:

cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'

然而,这需要第一列和最后一列并将它们合并到一个列表中。有没有办法用 sed 和 awk 命令清楚地打印第一列和最后一列?

输入示例:

foo|dog|cat|mouse|lion|ox|tiger|bar

答案1

差不多了。只需将两个列引用放在一起即可。

cat logfile | sed 's/|/ /' | awk '{print $1, $8}'

另请注意,这里不需要cat

sed 's/|/ /' logfile | awk '{print $1, $8}'

另请注意,您可以看出awk列分隔符是|, 而不是空格,因此您也不需要sed

awk -F '|' '{print $1, $8}' logfile

按照建议经过迦勒,如果您想要一个仍然输出最后一个字段的解决方案,即使不正好是八个,您可以使用$NF

awk -F '|' '{print $1, $NF}' logfile

此外,如果您希望输出保留|分隔符,而不是使用空格,您可以指定输出字段分隔符。不幸的是,它比仅仅使用标志有点笨拙-F,但这里有三种方法。

  • awk您可以在 BEGIN 块中分配输入和输出字段分隔符本身。

    awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
    
  • awk您可以在从命令行调用时通过标志分配这些变量-v

    awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
    
  • 或者简单地:

    awk -F '|' '{print $1 "|" $8}' logfile
    

答案2

awk无论如何,你正在使用:

awk '{ print $1, $NF }' file

答案3

只需从第一个到最后|一个替换为|(或空格,如果您愿意):

sed 's/|.*|/|/'

请注意,虽然没有特殊的sed实现|(只要扩展-E正则表达式在某些实现中未启用-r),\|其本身在 GNU 等实现中很特殊sed。所以你应该不是|如果您希望它与字符匹配,请转义|

如果用空格替换,并且输入可能已经包含只有一个的行|,那么,您必须特殊对待它,因为|.*|它们不会匹配。那可能是:

sed 's/|\(.*|\)\{0,1\}/ /'

(即使该部分成为.*|可选)或者:

sed 's/|.*|/ /;s/|/ /'

或者:

sed 's/\([^|]*\).*|/\1 /'

如果您想要第一个和第八个字段,而不管输入中的字段数量如何,那么只需:

cut -d'|' -f1,8


(假设输入形式有效文本,所有这些都可以与任何符合 POSIX 标准的实用程序一起使用(特别是,sed如果输入具有在当前语言环境中不形成有效字符的字节或字节序列,则这些通常不起作用,例如printf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'在UTF-8 语言环境))。

答案4

看来您正在尝试获取由 分隔的文本的第一个和最后一个字段|

我假设您的日志文件包含如下文本,

foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo

你想要的输出是这样的

foo bar
bar foo

如果是,那么这是您的命令

通过 GNU sed,

sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file

例子:

$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar

相关内容