切不切的时候应该用什么?

切不切的时候应该用什么?

cities我有一个这样的文件:

[1598] San Diego, US (inactive)
[4517] St Louis, US (inactive)
[6346] Orlando, US (inactive)

我想剪掉城市名称,这样我就有:

San Diego
St Louis
Orlando

这是我能想到的最好的:

cut -d ',' -f1 cities | cut -d ']' -f2

但这仍然在名字前留下了一个空格。是否有一个cut类似的命令可以使用它接受多个字符的分隔符以便我可以继续]

答案1

awk(还检查awk信息)对于这类问题来说很漂亮。尝试:

awk -F'[],] *' '{print $2}' cities

这将字段分隔符定义-F[],] *- 表示出现一次右方括号或逗号,后跟零个或任意数量的空格。当然,您可以更改它以满足任何要求。阅读正则表达式。

分割线后,您可以对分割结果执行您想要的操作。在这里,我决定仅使用 打印第二个字段print $2。请注意,在 awk 指令周围使用单引号非常重要,否则 $2 会被 shell 替换。

答案2

cut您可以将管道中的最后一个修改为:

cut -d ' ' -f2-

上面的意思是字段分隔符是空格,我们想要选择从第二个开始的所有字段。完整的序列变为:

cut -d ',' -f1 cities | cut -d ' ' -f2-

答案3

对于更复杂的解析,您应该使用sed(1):

sed -e 's/\[[0-9]\+\] \([^,]\+\),.*/\1/' cities

或者使用-r来简化正则表达式,如建议的那样佩波卢安:

sed -re 's/\[[0-9]+\] ([^,]+),.*/\1/' cities

答案4

当 sed 和 grep 变得太困难时,我通常使用 Perl。

有多种方法可以用 Perl 编写它。例如,您可能希望它速度快,或者您可能希望它处理输入中的轻微意外问题(例如,预期有两个空格)。

一种明显的方法(假设 id 是数字,城市是字母,状态是字母):

while (<>) {
    if (/^\[\d+\] (\w+(?: \w+)*), \w+ \(\w*\)$/) {
        my $city = $1;
        print "$city\n";
    }
}

或者更慢但更宽容(进行更多回溯):

while (<>) {
    if (/^.*\]\s+(.*),.*$/) {
        my $city = $1;
        print "$city\n";
    }
}

或者更快(字段在第一次出现右括号时停止):

while (<>) {
    if (/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/) {
        my $city = $1;
        print "$city\n";
    }
}

从命令行而不是脚本,您可以使用该-n选项,它基本上添加了while (<>) { BLOCK }循环:

perl -ne '/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/ and print $1, "\n";' cities

或者,如果您希望用法类似于 cut,则可以使用该-F选项,该选项类似于 awk 的-F选项,例如:

perl -a -n -F'/[],]\s+/' -e 'print $F[1], "\n"' cities

这种方式显然假设没有字段将包含任何分隔符。

相关内容