Bash: "nl" : 去除每个行号前多余空格的最佳方法是什么?



我有这样的代码:

sourceStr="abc
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn";
nl -s ". " <<< "$sourceStr"

输出为:

1. abc
2. efg
3. jkm
4. lmn
5. efg
6. jkm
7. lmn
8. efg
9. jkm
10. lmn
11. efg
12. jkm
13. lmn

我想去掉行号前的空格。是一个多行正则表达式搜索,并替换输出"是标准的方法,还是有更好的方法,例如,编辑nl命令,将其输出更改为不包括额外的空格?

man nl列出宽度标志。

- w, number-width =号使用NUMBER列表示行号

所以尝试:

nl -w1 -s". " <<< "$sourceStr"
输出:

1. abc
2. efg
3. jkm
4. lmn
5. efg
6. jkm
7. lmn
8. efg
9. jkm
10. lmn
11. efg
12. jkm
13. lmn

使用sed.

#!/bin/bash
sourceStr="abc
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn";

nl -s ". " <<< "$sourceStr" | sed 's/^ *//g'

输出:

Chris@DESKTOP-BCMC1RF ~
$ ./test.sh
1. abc
2. efg
3. jkm
4. lmn
5. efg
6. jkm
7. lmn
8. efg
9. jkm
10. lmn
11. efg
12. jkm
13. lmn

有很多方法可以做到。一、使用tr

#!/bin/bash
sourceStr="abc
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn"
nl -s ". " <<< "$sourceStr" | tr -d ' '

但这将删除所有空格,而不仅仅是前缀。像这样:

./so.bash
1.abc
2.efg
3.jkm
4.lmn
5.efg
6.jkm
7.lmn
8.efg
9.jkm
10.lmn
11.efg
12.jkm
13.lmn

如果只删除前缀,将nl行替换为:

nl -s ". " <<< "$sourceStr" | sed "s#^[ t]*(..*)*#1#"
  • ^:以
  • 开头
  • [ t]*:任意数量的空格或制表符
  • (..*):.是数字后面的点。.*匹配其他所有内容。()将它们组合在一起
  • 1:替换为( )定义的组。

现在的输出是:

./so.bash 
1. abc
2. efg
3. jkm
4. lmn
5. efg
6. jkm
7. lmn
8. efg
9. jkm
10. lmn
11. efg
12. jkm
13. lmn

与其他解决方案相比,我下面的解决方案的优点是它们对齐.时不会在左侧添加多余的填充。即:

1. abc
2. efg
3. jkm
4. lmn
5. efg
6. jkm
7. lmn
8. efg
9. jkm
10. lmn
11. efg
12. jkm
13. lmn

关键是,为了获得最小和对齐的缩进,您必须知道行号本身将采取的最大宽度。以下是awknl+colrm的解决方案:

awk:

解这只是用awk而不是nl对所有行进行编号:

sourceStr="abc
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn";
# Count the number of lines
total=$(wc -l <<<"$sourceStr")
# Pass the total into awk, using a HERE document for the awk code
awk -v total=$total -f <(cat <<'HERE'
BEGIN{
# Calculate the width of the largest line number
# using log10(lineNum). Because log in awk is natural log,
# log10(x) = log(x) / log(10)
maxWidth=int(log(total)/log(10))
}
{
# Calculate the width of the current line number + 1
n=(int(log(NR)/log(10)) + 1);
# Print spaces so that the indentation for all line numbers
# is the same
for(i=0;i<=maxWidth-n;i++){
# Use printf because it doesn't print a newline
printf " "
}
# Print the line number and content
print NR ". " $0
}
# End the HERE document
HERE
) <<< "$sourceStr"

给出上面的结果。

nl和colm:

这将查看nl输出的最后一行,以计算使用colrm要删除多少额外的缩进。

sourceStr="abc
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn
efg
jkm
lmn";
# Add line numbers
results="$(nl -s '. ' <<< "$sourceStr")"
# Count the number of spaces at the beginning of the last line
# 1) use tail to get the last line
# 2) use sed to remove everything except the starting spaces
# 3) use wc to count the spaces
indent=$(("$(tail -n1 <<< "$results" | sed -E 's/^( *).*/1/g' | wc -m)" - 1))
# Remove the first X spaces from all the lines
colrm 1 $indent <<< "$results"

给出相同的结果。

对于column

也可以这样做
nl -s ". " <<< "$sourceStr" | column -o " " -R 1 -t

选项- r1将第一列中的数字右对齐。

column from util-linux 2.36.1

使用一个awk来完成这一切可能会很混乱。在链中操作要直接得多:

jot -s '' -c - 97 122 | mawk 'gsub(".",$_,$_) + 
gsub(".",$_,$_) +   
gsub(".","&n")' FS='^$' RS= | shuf |

mawk '$!NF = substr(_="", gsub("...", "nt  " (
substr("__________", ++_, int(length($!_++)/++_)))"= &", 
$!(NF = NF))) $!_' RS= OFS= FS='n'                |
mawk -F'^$' 'sub("  [_]+=", sprintf("%#478.f", NR))_' | 

——需要筛选的行太多了…

mawk -F'^$' -Wi '_<(_+=(_==NR)*__)' _=127 __=10987

.

127. wqy
11,114. xry
22,101. ice
33,088. qog
44,075. ecl
55,062. cfv
66,049. afk
77,036. zzv
88,023. huh
99,010. ujw
109,997. ojp
120,984. uxi
131,971. qri
142,958. emd

如果感觉左侧空白太多,则提取更短的格式化子字符串

$ awk '$0=NR". "$0' <<<"$sourceStr" 
1. abc
2. efg
3. jkm
4. lmn
5. efg
6. jkm
7. lmn
8. efg
9. jkm
10. lmn
11. efg
12. jkm
13. lmn
$ awk '{printf "%2d. %sn",NR,$0}' <<<"$sourceStr" 
1. abc
2. efg
3. jkm
4. lmn
5. efg
6. jkm
7. lmn
8. efg
9. jkm
10. lmn
11. efg
12. jkm
13. lmn

最新更新