关于linux:如何使用’cut’查找最后一个字段

How to find the last field using 'cut'

如果不使用sedawk,而仅使用cut,那么当字段数未知或每行更改时,如何获取最后一个字段?


您可以尝试这样的事情:

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

说明

  • maps.google.com的反向为moc.elgoog.spam
  • cut使用点作为定界符并选择第一个字段,即moc
  • 最后,我们再次将其反转(感谢提醒@tom)以获得com


使用参数扩展。这比包括cut(或grep)的任何种类的外部命令要高效得多。

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

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


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

1
grep -o '[^,]*$'

用逗号分隔其他定界符。


没有awk吗?
但是使用awk是如此简单:

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

AWK是一种功能更强大的工具,可以放在口袋里。
-F如果用于字段分隔符
NF是字段数(也代表最后一个的索引)


有多种方法。您也可以使用它。

1
2
3
echo"Your string here"| tr ' ' '
'
| tail -n1
> here

显然,tr命令的空格输入应替换为所需的定界符。


这是仅使用cut的唯一可能解决方案:

echo"s.t.r.i.n.g." | cut -d'.' -f2-
[repeat_following_part_forever_or_until_out_of_memory:] | cut -d'.' -f2-

使用此解决方案,字段的数量确实可以是未知的,并且会不时变化。但是,由于行长不得超过LINE_MAX个字符或字段(包括换行符),因此,绝对不能将任意数量的字段作为此解决方案的实际条件。

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


如果您的输入字符串不包含正斜杠,则可以使用basename和一个子shell:

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

这不使用sedawk,但是也没有使用cut,因此我不确定它是否可以用措词回答问题。

如果处理可能包含正斜杠的输入字符串,这将无法正常工作。解决该问题的方法是将正斜杠替换为您知道不是有效输入字符串的一部分的其他字符。例如,文件名中也不允许使用竖线(|)字符,因此可以使用:

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

以下实现朋友的建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ 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。
好吧,我想是回声。


如果您有一个名为filelist.txt的文件,该文件是诸如以下内容的列表路径:
c:/dir1/dir2/file1.h
c:/dir1/dir2/dir3/file2.h

那么您可以执行以下操作:
rev filelist.txt |切-d" /" -f1 |转速


我意识到,只要确保存在尾随定界符,它就会起作用。因此,在我的情况下,我有逗号和空格分隔符。我在最后添加一个空格;

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