什么命令将提供制表符分隔的文本文件并将每行剪切为 80 个字符?

use*_*082 11 shell-script text-processing tabulation columns

我有(有时)制表符分隔数据的多行文本文件。我想输出文件以便我可以浏览它 - 所以我只想看到每行的前 80 个字符(我设计的文本文件将重要的内容放在每一行的前面)。

我以为我可以使用 cat 读取文件的每一行,并将每一行发送到管道中的下一个命令:

cat tabfile | cut -c -80
Run Code Online (Sandbox Code Playgroud)

但这似乎坏了。我试着四处游荡,grep 似乎工作 - 但后来我发现,不,它没有(不是文件中的每一行都有 80 多个字符) - 似乎制表符被视为单个字符。

我试过:

cat tabfile | tr \t \040 | cut -c -80
Run Code Online (Sandbox Code Playgroud)

尽管这会通过消除空白可读性来稍微破坏我的数据。但这没有用。也没有:

cat tabfile | tr \011 \040 | cut -c -80
Run Code Online (Sandbox Code Playgroud)

也许我使用 tr 错了?我之前遇到过 tr 问题,想删除多个空格(似乎我在这台机器上可以访问的 tr 版本有一个 -s 选项来压缩多个字符 - 我可能需要更多地使用它)

我敢肯定,如果我搞砸了,我可以使用 perl、awk 或 sed 或其他方法来做到这一点。

但是,我想要一个使用(POSIX?)常规命令的解决方案,以便它尽可能具有可移植性。如果我最终使用 tr,我可能最终会尝试将制表符转换为字符,也许会进行计算,削减计算,然后将这些字符重新转换为制表符以进行输出。

它不需要是一行/直接在命令行上输入 - 脚本就可以了。


有关选项卡文件的更多信息:

我使用制表符来分隔字段,因为有一天我可能想将数据导入其他程序。所以我倾向于在内容之间只有一个标签。但我也使用制表符将内容与垂直列对齐,以在查看纯文本文件时提高可读性。这意味着对于某些文本,我用空格填充内容的末尾,直到我到达选项卡将工作的位置,以将下一个字段与其上方和下方的字段对齐。

DarkTurquoise #00CED1 海洋、天空、划艇自然
MediumSpringGreen #00FA9A 适用于树木魔法  
Lime #00FF00 仅用于春鸡和果蔬$

mik*_*erv 11

我认为您正在寻找expand和/或unexpand. 看来您正试图确保 a \tb 宽度计为 8 个字符而不是单个字符。fold也会这样做,但它会将其输入包装到下一行而不是截断它。我想你想要:

expand < input | cut -c -80
Run Code Online (Sandbox Code Playgroud)

expand并且unexpand都是POSIX 指定的

  • expand实用程序应将文件或标准输入写入标准输出,其中\ta 字符替换为一个或多个填充到下一个制表位所需的空格字符。任何退格字符都应复制到输出中,并导致制表位计算的列位置计数减少;列位置计数不应减少到零以下。

很简单。那么,让我们看看它的作用:

unset c i; set --;                                                             
until [ "$((i+=1))" -gt 10 ]; do set -- "$@" "$i" "$i"; done                      
for c in 'tr \\t \ ' expand;  do eval '                                           
    { printf "%*s\t" "$@"; echo; } | 
      tee /dev/fd/2 |'"$c"'| { 
      tee /dev/fd/3 | wc -c >&2; } 3>&1 |
      tee /dev/fd/2 | cut -c -80'
done
Run Code Online (Sandbox Code Playgroud)

until顶部的循环获取一组数据,例如...

1 1 2 2 3 3 ...
Run Code Online (Sandbox Code Playgroud)

正是printf这个带有%*sarg 填充标志,所以对于集合中的每一个,printf都将填充与参数数量一样多的空格。每一个都附加一个\tab 字符。

所有的tees 都用于显示每个过滤器在应用时的效果。

效果如下:

1        2        3        4        5        6        7        8                9               10
1  2   3    4     5      6       7        8         9         10 
1  2   3    4     5      6       7        8         9         10 
66
1        2        3        4        5        6        7        8                9               10
1        2        3        4        5        6        7        8                9               10 
1        2        3        4        5        6        7        8                
105
Run Code Online (Sandbox Code Playgroud)

这些行排成两组,例如...

  1. 输出 printf ...; echo
  2. tr ...或的输出expand
  3. 输出 cut
  4. 输出 wc

前四行是tr过滤器的结果——其中每个\tab 都被转换为一个空格

后四个是expand链的结果。