假设我有一个文件:
Line1
Line2
Line3
Line4
Line5
Line6
Line7
Line8
Line9
Line10
Line11
Line12
…
我想得到:
Line1
Line2
Line3
Line7
Line8
Line9
Line13
Line14
Line15
意思是我想要奇数三行(含)。
我有一些想法,比如for (i=1, i<=FR, i+5), {sed -n,'i, i+1p' } < input
你能告诉我 sed 中 for 循环的结构吗?以及如何纠正这个问题?
答案1
尝试这个
awk 'NR % 6 == 1 || NR % 6 == 2 || NR % 6 == 3' filename.txt > output.txt
答案2
seq 20|
sed 'n;n;n;$!N;$!N;d'
n
用 ext 输入行覆盖当前行n
并打印它覆盖的模式空间(除非你这样做sed -n
或sed -e'#n'
),所以我们这样做了三次,然后我们缓冲了另外两个附加的输入行,并d
删除了其中的很多。
1
2
3
7
8
9
13
14
15
19
20
我的另一件事是这样的:
sed -ne:p -e'$p;N;s/\n/&/2p;tn' -ebp \
-e:n -en \
-e:d -e'N;s/\n/&/2;t' -ebd
它将首先缓冲两个附加的N
ext 输入行,并对\n
添加的 ewlines 进行计数,如果当前行是最后一行或者缓冲区已满,则打印,然后用 ext 输入行覆盖该行n
,并在删除这些行之前再缓冲两个行。
也可以这样写:
sed -ne:p -e'$p;N;s/\n/&/2p;tn' \
-ebp -e:n -e'n;n;n'
但 ests 的优点t
是你可以轻松地对其进行参数化,如下所示:
altl(){ sed -ne":t$(n=0 nt='\n\t' b=$nt\b
while [ "$#" -gt "$((!(n+=1)))" ] &&
c=${1%?} p=${1##*[!p]} \
l=$nt${p:+\$p;} p=$nt$p${p:+;}n
do case $1 in
(''|0*|*[!0-9]*?|*[!pd])
>&2 printf '"%s":\tARG ERR\n' "$1"
kill -2 0;;
(1?|?|$((c-=1))) ! :; esac &&
printf "\n:$n.0${l}N;%s$c;t$n.1%b" \
's/\n/&/' "$b$n.0\n:$n.1"
shift; printf %b "$p${1+\c}${nt}bt"
done)"
}
事实上,做另一个也不是特别困难:你只需要一次打印这么多[Nn]
ssed
就可以实现它。所以也许我写上面的内容是浪费时间。但它确实有效:
( set -x
seq 150 |
altl p 40d p p 10d 5p
)
### This is the sed script the function's shell loop writes.
### We see it because I enabled -xtrace output on stderr.
:t
p;n
:2.0
N;s/\n/&/39;t2.1
b2.0
:2.1
n
p;n
p;n
:5.0
N;s/\n/&/9;t5.1
b5.0
:5.1
n
:6.0
$p;N;s/\n/&/4;t6.1
b6.0
:6.1
p;n
bt
### This ends the sed script.
### The rest is sed's stdout.
1
42
43
54
55
56
57
58
59
100
101
112
113
114
115
116
117