输入:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
预期产量:
1
2
3
4
因此,我需要在输出文件中仅具有文件的1、5、9、13值。这该怎么做?
输入:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
预期产量:
1
2
3
4
因此,我需要在输出文件中仅具有文件的1、5、9、13值。这该怎么做?
Answers:
使用AWK:
awk '!((NR - 1) % 4)' input > output
弄清楚这是如何工作的,留给读者练习。
NR % 4 == 1
会更清晰的IMO。
使用split
(GNU coreutils):
split -nr/1/4 input > output
-n
生成CHUNKS
输出文件和CHUNKS
作为
r/K/N
使用循环分配,仅将N的第K个输出到stdout,而不拆分行/记录使用GNU sed
:
sed '1~4!d' < input > output
符合标准sed
:
sed -n 'p;n;n;n' < input > output
使用1
和4
in $n
和$i
变量:
sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
Python版本,只是为了好玩:
with open('input.txt') as f:
for i, line in enumerate(f.readlines()):
if i%4 == 0:
print(line.strip())
enumerate(f)
应该能够在消耗更少内存的情况下完成这项工作
readlines
(因此将整个文件插入内存),则可以使用f.readlines()[::4]
来获取第四行。这样就可以使用了print(''.join(f.readlines()[::4]))
。
POSIX sed
:此方法使用posixly sed,因此可以在任何地方运行,或至少尊重posix的那些sed。
$ sed -ne '
/\n/!{
H;s/.*//;x
}
:loop
$bdone
N;s/\n/&/4
tdone
bloop
:done
s/.//;P
' input.file
另一个是用于可扩展性目的的编程sed代码生成:
$ code=$(yes n | head -n 4 | paste -sd\; | sed s/n/p/)
$ sed -ne "$code" input.file
Perl
:我们填充数组A直到大小为4。然后,我们打印其第一个元素并清除数组。
$ perl -pe '
$A[@A] = @A ? <> : $_ while @A < 4;
$_ = (splice @A)[0];
' input.file
纯重击:
mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%s\n" "${lines[$i]}"
done
mapfile是Bash 4中添加的内置函数,它将标准输入读取到数组中,此处命名为lines
,每个条目一行。该-t
选项将删除最后的换行符。
如果要从第4行开始每四行打印一次,则可以使用mapfile
的callback选项在一个命令中执行此操作,该命令-C
每隔多行运行提供的代码,间隔为-c
。当前数组索引和要分配的下一行作为参数提供给代码。
mapfile -t -c4 -C 'printf "%.0s%s\n"' < input
这使用printf
内置的;格式代码%.0s
禁止显示第一个参数(索引),因此仅打印该行。
您可以使用同一命令从行1、2或3开始打印每四行,但input
在将行送入之前必须先添加3、2或1行mapfile
,我认为这比它值得的麻烦多。 。
这也适用:
mapfile -t lines < input
printf "%s%.0s%.0s%.0s\n" "${lines[@]}"
在这里,一次printf
消耗数组的四个条目lines
,只打印第一个,用跳过其他三个%.0s
。我不喜欢这样,因为您必须手动调整格式字符串以获取不同的时间间隔或起点。
sed -n '1~4p'