给定文件中由特定字符分隔的分栏文本,如何截断特定列或所有列的宽度?
用例是我正在读取一些具有空格分隔列的日志文件。日志中的某些列是非常长的 URL,导致文件难以阅读。我并不真正关心网址的全部内容,因此我想将这些列的长度截断为更具可读性。
我很想知道如何指定要截断的特定列,但实际上我只需要弄清楚如何截断长度大于 N 的所有列。
到目前为止,我已经找到了 utils column
、colrm
和cut
,它们似乎都与此类似,但没有任何东西能满足我的需求。
(最理想的是,如果有一个已编译的实用程序已经做到了这一点,这将是最好的,但我也很高兴找到一种方法来使用sed
、awk
、perl
等来做到这一点。)
答案1
sed 's/\([^,]\{0,3\}\)[^,]*/\1/g'
会将每列截断为前 3 个字符。列由“,”字符分隔。
怎么运行的:
它(贪婪地)找到一个由 0 到 3 个字符(除 ',' 之外)组成的字符串,并将其记住为第一组(由 \1 引用)
然后它会尝试尽可能多地查找“,”以外的字符。
所有这些都替换为组 1(即前 3 个字符)。
由于
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
也许你可以用这个!?