为最后的每一行生成序列号..修改了帖子,有人可以对此提供帮助和建议吗

为最后的每一行生成序列号..修改了帖子,有人可以对此提供帮助和建议吗

我有这个查询

sed '/./=' abc.txt| sed '/./N; s/\n/, /' >> as.dat


source file has 3 rows like below
a
b
c

当使用以下命令时,它会给我这样的结果

Output 

    1 a
    2 b 
    3 c 

但我想要这样的命令输出

Output 

    a 1 
    b 2 
    c 3 

答案1

Unix 有这些奇妙的小工具,称为cutpaste。该cut工具将从其输入中提取一组列,同时paste插入列。我们将使用这些。

我不会太关心你的管道(现在,但请参阅这个答案的结尾),我只关心切换列的问题。

假设我有一个名为的文件中的数据cols.txt

$ cat cols.txt
1 a
2 b
3 c

$ paste -d ' ' cols.txt cols.txt
1 a 1 a
2 b 2 b
3 c 3 c

paste实用程序通常会在列之间插入一个制表符,但在这里我们告诉它插入一个空格 ( -d ' ')。

paste然后只需从with 的输出中提取第二列和第三列即可cut

$ paste -d ' ' cols.txt cols.txt | cut -d ' ' -f 2,3
a 1
b 2
c 3

我们已经说过cut,我们有空格作为“字段分隔符”(-d ' ',否则需要制表符),并且我们希望有字段 2 和 3 ( -f 2,3)。 (不幸的是,只要求原始输入中的cut列“ ”2,1不是交换列。)

所以最终这里真的不需要混乱的正则表达式魔法。

回到你的管道。让我们废弃它吧。似乎您想将行号插入到每一行中。还有另一个 Unix 工具叫做nl(“数字线”):

$ nl abc.txt
     1  a
     2  b
     3  c

默认情况下,您会获得每个非空行的行号,前面有一些用于填充的空格,并通过制表符与原始行分隔。您是否也想对空行进行编号,请使用

$ nl -b a abc.txt

据我所知,您无法nl将行号放在行的右侧,但这不是问题,因为我们有一个解决方案可以交换两列输入:

$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a            1
b            2
c            3

我们不再需要在这里指定分隔符。nl将在每行的开头插入空格,后跟行号和制表符。paste在列之间插入制表符,并cut在制表符上剪切,这样它就可以工作了。

如果您希望列之间有一个空格(现在有一个制表符和一些空格),请添加| tr -s '\t' ' '到命令中。这会将所有制表符更改(“音译”)为空格,并将-s所得的连续空格“压缩”( ) 为一个空格。

如果您想要一个逗号和一个空格,请改用| tr '\t ' ', '

$ paste  <(nl abc.txt) <(nl abc.txt) | cut -f 2,3 | tr -s '\t ' ', '
a, 1
b, 2
c, 3

这适用于每行包含多个单词的文件,但对于包含制表符的文件将失败:

$ cat abc.txt    # no tabs in this file though
a text     there is a
b goes     hole in my
c here     pants

$ paste  <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a text     there is a        1
b goes     hole in my        2
c here     pants             3

答案2

sed '/./=' | sed '/./{N; s/\(.*\)\n\(.*\)/\2 \1/;}'

awk会更直接:

awk '/./ {$0 = $0 " " NR}; {print}'

您只会对包含至少一个字符的行进行编号,这似乎很奇怪。如果这不是您的意图,那么您可以将其更改为:

sed = | sed 'N; s/\(.*\)\n\(.*\)/\2 \1/'
awk '{print $0, NR}'

答案3

完成任务的另一种方法是使用nl带选项的命令-nln。这对文件中的行进行编号。例如..

echo -e "a\nb\nc\n" | nl -nln -

会产生:

 1  a
 2  b
 3  c

现在剩下的就是将数字移到单词的右侧。这可以使用sed以下方法完成:

sed 's/^\([^ \t]*\)[ \t]*\([^ \t].*\)$/\2 \1/g'

它的作用是找到一行中的第一个单词(要找到第一个单词,我们必须只包含除空格和制表符之外的那些字符。这是使用 完成的[^ \t])并将其记住为\1以及 空格后面的行部分 为\2并替换与 的行\2 \1

所以最终的命令是

cat filename | nl -nln - | sed 's/^\([^ \t]*\)[ \t]*\([^ \t].*\)$/\2 \1/g'

相关内容