【发布时间】:2019-11-14 06:04:26
【问题描述】:
我有一个 bash 管道,例如$ src_prog | dst_prog.
我可以在管道中插入什么命令,以便每隔一个字节被静默丢弃?
我希望 dst_prog 只接收字节 0,2,4,6...
附:这需要适用于一个字节的所有值,而不仅仅是 ASCII 或 UTF8。
【问题讨论】:
我有一个 bash 管道,例如$ src_prog | dst_prog.
我可以在管道中插入什么命令,以便每隔一个字节被静默丢弃?
我希望 dst_prog 只接收字节 0,2,4,6...
附:这需要适用于一个字节的所有值,而不仅仅是 ASCII 或 UTF8。
【问题讨论】:
更新另一个 awk:
$ echo -ne abcdef\\n123456\\nåäö |
LC_ALL=C awk -F "" '{
for(i=1;i<=NF;i++) # iterate all chars
if(i%2!=p) # output every other char
printf $i
if(p=((p&&NF%2)||(!p&&!(NF%2)))) # xor
printf "\n" # handle newlines, all but the last
}'
输出:
ace
246��
输出到hexdump -C:
00000000 61 63 65 0a 32 34 36 c3 c3 c3 0a |ace.246....|
0000000b
它处理换行符但在最后一个换行符处失败(echo -n 但请参阅转储的结尾)。
或者也许你可以使用这个小 c 程序:
$ cat foo.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c;
int i=0;
while((c=getchar()) != EOF) {
if((i=!i)!=0)
printf("%c",c);
}
exit(0);
}
然后:
$ gcc -Wall foo.c && echo -n 1234äö | ./a.out | hexdump -C
00000000 31 33 c3 c3 |13..|
00000004
【讨论】:
您可以使用fold 将每个单字节放入单行,使用awk 删除奇数行并使用tr 将其连接回来:
echo abcdefgh12345678 | fold -b -w 1 | awk 'NR%2==1' | tr -d "\n"
aceg1357
附: -b 标志如果用于字节(不是字符),但它似乎只适用于单字节文本数据(ASCII)
【讨论】:
你可以使用 Ruby:
$ cat a.out | wc -c
9456
$ cat a.out | ruby -ne '$_.each_char.with_index{|c,i| print c if i.even?}' | wc -c
4728
相同但转储字节而不是计数:
$ cat a.out | hexdump -Cn10
00000000 7f 45 4c 46 02 01 01 00 00 00 |.ELF......|
$ cat a.out | ruby -ne '$_.each_char.with_index{|c,i| print c if i.even?}' | hexdump -Cn10
00000000 7f 4c 02 01 00 00 00 00 02 3e |.L.......>|
【讨论】: