打印奇数行,打印偶数行

打印奇数行,打印偶数行

我想打印文件中的奇数行和偶数行。

我发现这个 shell 脚本使用了 echo。

#!/bin/bash
# Write a shell script that, given a file name as the argument will write
# the even numbered line to a file with name evenfile and odd numbered lines
# in a text file called oddfile.
# -------------------------------------------------------------------------
# Copyright (c) 2001 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------

file=$1
counter=0

eout="evenfile.$$" # even file name
oout="oddfile.$$" # odd file name

if [ $# -eq 0 ]
then
    echo "$(basename $0) file"
    exit 1
fi

if [ ! -f $file ]
then
    echo "$file not a file"
    exit 2
fi

while read line
do
    # find out odd or even line number
    isEvenNo=$( expr $counter % 2 )

    if [ $isEvenNo -ne 0 ]
    then
        # even match
        echo $line >> $eout
    else
        # odd match
        echo $line >> $oout
    fi
    # increase counter by 1
    (( counter ++ ))
done < $file
echo "Even file - $eout"
echo "Odd file - $oout"

但是有没有一种方法可以在一行中完成呢?

是的,使用awk,我读。

偶数行:

awk 'NR % 2' filename

奇数行:

awk 'NR % 2 == 1' filename

但这对我不起作用。根据 diff ,两者产生相同的输出。与原始文件相比,它们的长度确实只有一半,并且都包含奇数行。难道我做错了什么?

答案1

我更喜欢尽可能兼容 POSIX,所以我想我应该发布这个替代方法。我经常在xargs管道之前使用它们来破坏文本。

打印偶数行,

sed -n 'n;p'

打印奇数行,

sed -n 'p;n'

虽然我经常使用awk,但对于此类任务来说它有点过分了。

答案2

对于偶数,代码应该是

awk 'NR%2==0' filename

& 对于奇数

awk 'NR%2==1' filename

答案3

这很容易:

 sed -n 2~2p filename

将打印文件名中的偶数行

sed -n 1~2p filename

将打印奇数行。

答案4

您可以通过一次sed调用来完成此操作,无需读取文件两次:

sed '$!n
w even
d' infile > odd

或者,如果您喜欢一行:

sed -e '$!n' -e 'w even' -e d infile > odd

请注意,如果文件仅包含一行,则这些不会给出预期结果(该行将被w写入,even而不是odd因为第一行n未执行)。为了避免这种情况,请添加一个条件:

sed -e '$!n' -e '1!{w even' -e 'd}' infile > odd

怎么运行的 ?好吧,它使用三个sed命令:
n- 如果不在最后一行打印模式空间stdout(被重定向到 file odd),用下一行替换它(所以现在它正在处理偶数行)并继续执行其余命令
w- 将模式空间附加到 file even
d- 删除当前模式空间并重新启动循环 -这样做的副作用是sed永远不会自动打印模式空间,因为它永远不会到达脚本的末尾

换句话说,n只在奇数行执行,wd只在偶数行执行。sed除非如我所说,输入由一行组成,否则永远不会自动打印。

相关内容