不使用sed或awk,只cut,当字段的数量未知或随每一行变化时,我如何得到最后一个字段?


当前回答

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

$ 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。 我想,还有回声。

其他回答

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

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

参见BashFAQ #100,了解bash中本地字符串操作的介绍。

没有awk ? 但是用awk很简单:

echo 'maps.google.com' | awk -F. '{print $NF}'

AWK是一个更强大的工具,可以放在你的口袋里。 -F if用于字段分隔符 NF是字段的数量(也表示最后一个字段的索引)

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

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

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

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

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

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

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

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

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

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

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

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