如何将文件中的所有列截断为特定长度?

如何将文件中的所有列截断为特定长度?

给定文件中由特定字符分隔的分栏文本,如何截断特定列或所有列的宽度?

用例是我正在读取一些具有空格分隔列的日志文件。日志中的某些列是非常长的 URL,导致文件难以阅读。我并不真正关心网址的全部内容,因此我想将这些列的长度截断为更具可读性。

我很想知道如何指定要截断的特定列,但实际上我只需要弄清楚如何截断长度大于 N 的所有列。

到目前为止,我已经找到了 utils columncolrmcut,它们似乎都与此类似,但没有任何东西能满足我的需求。

(最理想的是,如果有一个已编译的实用程序已经做到了这一点,这将是最好的,但我也很高兴找到一种方法来使用sedawkperl等来做到这一点。)

答案1

sed 's/\([^,]\{0,3\}\)[^,]*/\1/g'会将每列截断为前 3 个字符。列由“,”字符分隔。

怎么运行的:

  1. 它(贪婪地)找到一个由 0 到 3 个字符(除 ',' 之外)组成的字符串,并将其记住为第一组(由 \1 引用)

  2. 然后它会尝试尽可能多地查找“,”以外的字符。

  3. 所有这些都替换为组 1(即前 3 个字符)。

  4. 由于g选项的原因,它会在每行执行多次此操作,截断所有列,而不仅仅是第一列。

编辑:

正如评论中指出的,如果您使用 ,则可以优化第一步([^,]\{3\}\)。这样我们只匹配确切地3 个字符。如果较少,我们不在乎,因为我们不必截断该字段。所以最终的命令是:

`sed 's/\([^,]\{3\}\)[^,]*/\1/g'`

答案2

我可以想象,文件按列结构并不重要,因为您写道您对长网址感到恼火。至少在解析文件而不是查看文件的情况下。

在这种情况下我的解决方案是

perl -pe 's%(http://\S+)%substr($1, 0, 15)%ge' <file_with_long_urls> | column -t

这会删除 url 后第十五个字符后面的所有字符http://

如果列不是由空格分隔而是由字符&(代表任意分隔符)分隔,我的解决方案如下所示

perl -pe 's%(http://\S+?)(?=&|$)%substr($1, 0, 15)%ge' <file_with_long_urls> | column -s '&' -t

也许你可以用这个!?

相关内容