修剪一行的最后3个字符,不使用sed或perl等

Rub*_*n10 38 unix shell sed

我有一个shell脚本输出这样的数据:

1234567890  *
1234567891  *
Run Code Online (Sandbox Code Playgroud)

我需要删除最后三个字符"*".我知道我可以通过

(whatever) | sed 's/\(.*\).../\1/'
Run Code Online (Sandbox Code Playgroud)

但我不想将sed用于速度目的.它将始终是相同的最后3个字符.

有什么快速清理输出的方法吗?

sit*_*n2k 168

这是一个老式的unix技巧,用于删除不使用sed OR awk的行中的最后3个字符...

> echo 987654321 | rev | cut -c 4- | rev

987654
Run Code Online (Sandbox Code Playgroud)

与之前使用'cut'的示例不同,这不需要知道线长.

  • 如果可以的话,我会给你买啤酒并按照你的方式发送. (22认同)
  • 老学校如地狱 (2认同)

pax*_*blo 30

我可以向你保证,bash没有比sed这项任务更快的速度.启动外部进程bash通常是个坏主意,但前提是你做了很多事情.

所以,如果你sed每一行输入开始一个过程,我会担心.但你不是.你只需要开始一个 sed为你完成所有工作的人.

但是,您可能会发现以下内容sed比您的版本快一些:

(whatever) | sed 's/...$//'
Run Code Online (Sandbox Code Playgroud)

所有这一切都是删除每一行的最后三个字符,而不是用更短的版本替换整行.现在也许更现代的RE引擎可以优化您的命令,但为什么要承担风险.

说实话,关于我能想到的唯一方法就是手工制作你自己的基于C的过滤程序.而这唯一的原因可能是速度比sed,因为你可以把你的处理需求的优势,你有额外的知识(sed必须考虑到广义游行,可能因为这样会比较慢).

不要忘记优化口头禅:"测量,不要猜!"


如果你真的想一次做一行bash(并且我仍然认为这是一个坏主意),你可以使用:

pax> line=123456789abc
pax> line2=${line%%???}
pax> echo ${line2}
123456789
pax> _
Run Code Online (Sandbox Code Playgroud)

您可能还想调查您是否确实需要提高速度.如果你将线条处理为一个大块,你会发现它sed很快.输入以下内容:

#!/usr/bin/bash

echo This is a pretty chunky line with three bad characters at the end.XXX >qq1
for i in 4 16 64 256 1024 4096 16384 65536 ; do
    cat qq1 qq1 >qq2
    cat qq2 qq2 >qq1
done

head -20000l qq1 >qq2
wc -l qq2

date
time sed 's/...$//' qq2 >qq1
date
head -3l qq1
Run Code Online (Sandbox Code Playgroud)

并运行它.这是我的(不是很快)R40笔记本电脑的输出:

pax> ./chk.sh
20000 qq2
Sat Jul 24 13:09:15 WAST 2010

real    0m0.851s
user    0m0.781s
sys     0m0.050s
Sat Jul 24 13:09:16 WAST 2010
This is a pretty chunky line with three bad characters at the end.
This is a pretty chunky line with three bad characters at the end.
This is a pretty chunky line with three bad characters at the end.
Run Code Online (Sandbox Code Playgroud)

这是在一秒钟内的20,000线,非常适合每小时只做一次的事情.


Lar*_*ang 12

假设所有数据的格式都与您的示例类似,请使用" cut "仅获取第一列.

cat $file | cut -d ' ' -f 1  
Run Code Online (Sandbox Code Playgroud)

或获得前10个字符.

cat $file | cut -c 1-10
Run Code Online (Sandbox Code Playgroud)

  • 无用的猫.今天保存一个进程并运行`cut -c 1-10 $ file`. (43认同)

A T*_*A T 11

$ x="can_haz"
$ echo "${x%???}"
can_
Run Code Online (Sandbox Code Playgroud)


小智 5

两者awksed有足够快,但如果你认为它很重要随意使用下列之一:

如果要删除的字符始终位于字符串的末尾

echo '1234567890  *' | tr -d ' *'
Run Code Online (Sandbox Code Playgroud)

如果它们可以出现在字符串中的任何位置,并且您只想在最后删除它们

echo '1234567890  *' | rev | cut -c 4- | rev
Run Code Online (Sandbox Code Playgroud)

所有命令的手册页将解释正在发生的事情.

不过我觉得你应该用sed.