如何找到最后一个字段使用'cut'

没有使用sedawk只有 cut,当字段的数量未知或随每一行变化时,我如何获得最后一个字段?

396288 次浏览

你可以尝试这样做:

echo 'maps.google.com' | rev | cut -d'.' -f 1 | rev

解释

  • rev将"maps.google.com"颠倒为moc.elgoog.spam
  • cut使用点(即'.')作为分隔符,并选择第一个字段,即moc
  • 最后,我们再次反转它以得到com

仅使用cut是不可能的。下面是使用grep的方法:

grep -o '[^,]*$'

用逗号替换其他分隔符。

解释:

  • -o (--only-matching)只输出与模式匹配的部分输入(默认是打印包含匹配的整行)。
  • [^,]是一个字符类,它匹配除逗号之外的任何字符。
  • *匹配前面的模式0次或更多次,因此[^,]*匹配0个或更多个非逗号字符。
  • $匹配字符串的结尾。
  • 将这些组合在一起,该模式将匹配字符串末尾的零个或多个非逗号字符。
  • 当有多个可能的匹配时,grep优先选择开始时间最早的那个。最后一个字段会被匹配。

完整的例子:

如果我们有一个名为data.csv的文件包含

one,two,three
foo,bar

那么grep -o '[^,]*$' < data.csv将输出

three
bar

使用参数展开。这比包括cut(或grep)在内的任何类型的外部命令都要有效得多。

data=foo,bar,baz,qux
last=${data##*,}

关于bash中本地字符串操作的介绍,请参见BashFAQ # 100

如果你有一个名为fillist .txt的文件,它是一个列表路径,如下所示: c: / dir1 dir2 / file1.h c: / dir1 dir2 / dir3 file2.h < / p >

那么你可以这样做: Rev filelist.txt | cut -d"/" -f1 | Rev

有多种方法。你也可以用这个。

echo "Your string here"| tr ' ' '\n' | tail -n1
> here

显然,tr命令的空格输入应该替换为所需的分隔符。

这是唯一可能的解决方案,只使用切割:

< p >回声“s.t.r.i.n.g。”| cut -d'。- f2 - [repeat_following_part_forever_or_until_out_of_memory:] | cut -d'。- f2 -

使用此解决方案,字段的数量确实可以是未知的,并且随时变化。但是,由于行长不能超过LINE_MAX字符或字段(包括新行字符),那么任意数量的字段永远不能作为该解决方案的实际条件。

是的,一个非常愚蠢的解决方案,但我认为这是唯一符合标准的解决方案。

下面实现了朋友的建议

#!/bin/bash
rcut(){


nu="$( echo $1 | cut -d"$DELIM" -f 2-  )"
if [ "$nu" != "$1" ]
then
rcut "$nu"
else
echo "$nu"
fi
}


$ export DELIM=.
$ rcut a.b.c.d
d

没有awk ?… 但是用awk就很简单了:

echo 'maps.google.com' | awk -F. '{print $NF}'
AWK是一个更强大的工具,可以放在你的口袋里。 -F if用于字段分隔符 NF是字段的个数(也表示最后一个字段的索引)

我意识到,如果我们只是确保后面的分隔符存在,它就可以工作。在我的例子中,我有逗号和空格分隔符。我在结尾加了一个空格;

$ ans="a, b"
$ ans+=" "; echo ${ans} | tr ',' ' ' | tr -s ' ' | cut -d' ' -f2
b

如果你的输入字符串不包含正斜杠,那么你可以使用basename和一个subshell:

$ basename "$(echo 'maps.google.com' | tr '.' '/')"

这没有使用sedawk,但它也没有使用cut,所以我不太确定它是否有资格作为问题的答案。

如果处理可能包含正斜杠的输入字符串,这就不能很好地工作。对于这种情况,一种变通方法是将正斜杠替换为其他一些您知道不是有效输入字符串的一部分的字符。例如,pipe (|)字符也不允许出现在文件名中,所以这是可行的:

$ basename "$(echo 'maps.google.com/some/url/things' | tr '/' '|' | tr '.' '/')" | tr '|' '/'

为这个老问题添加一个方法只是为了好玩:

$ cat input.file # file containing input that needs to be processed
a;b;c;d;e
1;2;3;4;5
no delimiter here
124;adsf;15454
foo;bar;is;null;info


$ cat tmp.sh # showing off the script to do the job
#!/bin/bash
delim=';'
while read -r line; do
while [[ "$line" =~ "$delim" ]]; do
line=$(cut -d"$delim" -f 2- <<<"$line")
done
echo "$line"
done < input.file


$ ./tmp.sh # output of above script/processed input file
e
5
no delimiter here
15454
info
除bash外,只使用cut。 我猜是echo。

使用perl的替代方法是:

perl -pe 's/(.*) (.*)$/$2/' file

你可以改变\t为任何file的分隔符

在处理表格数据时最好使用awk。你不需要听从命令。如果它可以通过awk实现,为什么不使用它呢?我建议您不要浪费宝贵的时间,只需使用少量命令就可以完成工作。

例子:

# $NF refers to the last column in awk
ll | awk '{print $NF}'