我有一个具有以下格式的文本文件,我想在这些行之后添加一条垂直线,然后增加数字:
c4-1 d e c
c d e c
e-2 f g2
e4 f g2
g8-4\( a-5 g f\) e4 c
g'8\( a g f\) e4 c
c-1 r c2
c4 r c2
我通过以下方式实现了行和编号while-loop
:
#!/bin/bash
while read -r line; do
if [ -z "$line" ]; then
echo
continue
fi
n=$((++n)) \
&& grep -vE "^$|^%" <<< "$line" \
| sed 's/$/\ \|\ \%'$(("$n"))'/'
done < file
并获得如下输出:
c4-1 d e c | %1
c d e c | %2
e-2 f g2 | %3
e4 f g2 | %4
g8-4\( a-5 g f\) e4 c | %5
g'8\( a g f\) e4 c | %6
c-1 r c2 | %7
c4 r c2 | %8
现在我希望添加垂直对齐并获得如下输出:
c4-1 d e c | %1
c d e c | %2
e-2 f g2 | %3
e4 f g2 | %4
g8-4\( a-5 g f\) e4 c | %5
g'8\( a g f\) e4 c | %6
c-1 r c2 | %7
c4 r c2 | %8
这意味着我需要以某种方式获取最长行的行长(此处:21 个字符)和每行的行长并添加空格的差异,我该如何实现呢?
您可以打印没有对齐的行,
column -t
并使用虚拟分隔符格式化输出:在这里,我在指示列的末尾
@
之前添加了一个 as 虚拟字符。|
最后的sed
命令用于在 . 之前删除一个额外的空格字符|
。需要选项-e
以在输出中保留空行。输出:
使用
awk
+ GNUwc
假设输入中的所有字符都是单宽的:普通 bash:适用于 bash 版本 >= 4.0
对于较旧的 bash 版本,将 mapfile 替换为 while-read 循环:这适用于 3.2 版
只是为了记录:(这非常慢,但这是我第一次尝试使用
wc -L
)肯定会使用 @Freddy 的答案
column
!虽然它正在使用一个额外的空间:
假设数据中没有
@
字符(在这种情况下,只需将@
此处使用的两个字符替换为另一个字符):这使用字符串
@| %
作为输出字段分隔符并打印输入后跟每行的行号(由此分隔符分隔),然后用于column
在@
字符上对齐(这些将被删除)。如果您喜欢
sed
或喜欢笨拙的正则表达式,您总是可以使用cat -n
or对行进行nl -b a
编号,然后将行号移动到行尾并在调用之前@| %
使用, 插入:sed
column
awk
用于两次读取文件,一次计算最大行长度 ( ),再次将m
行格式化为该长度。column
不在这里使用(或在最后一个解决方案中):请注意,文件名在命令行中给出了两次。
同上,但将文件作为数组(
a
)存储在内存中,最后按照最长的行长打印。磁盘访问有利于减少内存消耗: