我有一个文本文件,其内容如下:
abc.tar^@xxx.tar^@yyy.tar^@
举例来说,我将此内容放在一个名为 的文件中abc.txt
,我想拆分该内容并将前两个条目写入一个新文件中。
(例如),新文件将如下所示:
abc.tar^@xxx.tar^@
有没有命令可以执行这个操作?
答案1
这是:
awk -F"@" '{print $1"@"$2"@"}' abc.txt > newfile.txt
对你来说够好吗?
答案2
尝试运行:
sed -r -i 's/^(.*)@.*@.*$/\1/' file
答案3
我猜这个问题与那个, 正确的?
在这种情况下,用换行符替换“^@”不是更值得吗?在下面,我猜你的意思是“^@”,即 ASCII NUL 字节:
$ sed 's/\o000/\n/g' abc.txt | head -n 2
abc.tar
xxx.tar
所以你需要
sed 's/\o000/\n/g' abc.txt | head -n 2 > newfile.txt
解释
这会用换行符 ( \n
) 替换每个 NUL 字节 ( \o000
),这\o
意味着接下来是八进制表示法中的一个字节。然后将输出通过管道传送到head -n 2
提取前两行;结果行被重定向 ( >
) 到文件newfile.txt
。
但是,如果文件名用“^@”分隔对您来说很重要,则可以使用:
perl -nl000 -e '
$num_lines =2 ;
push @a,(split /\000/)[0..$num_lines-1];
print $_ for @a' abc.txt > newfile.txt
根据需要替换上面的值以从文件中$num_lines
获取第一行。$num_lines
解释
- 该
-n
开关指示perl
在输入文件的每一行上运行代码 - 该
-l000
序列指示perl
将输出记录分隔符(每个字符串后打印的字符)设置为 NUL 字节 (000
)。 - 该
-e
开关表明perl
后面的字符串是要执行的代码。 - 该
split
函数以 NUL 字节作为分隔符分割每个输入行,取出第一个$num_lines
([0..$num_lines-1]
) 结果并将它们放入数组中@a
。请注意,函数调用中没有指定“当前输入行”部分。这利用了这样一个事实:当没有提供参数时, Perl ($_
) 中的默认标量变量是函数(以及其他)的默认参数。split
- 最后的
foreach
循环打印每个元素@a
(再次注意循环$_
的默认迭代器是如何的foreach
)。由于我们已将输出记录分隔符设置为八进制000
,因此我们像以前一样得到由 NUL 字节分隔的结果。
答案4
awk 可以使用任何字符作为记录分隔符(默认使用换行符),但某些实现不支持空字节作为分隔符。 Gawk (GNU awk) 是大多数非嵌入式 Linux 安装上的默认 awk,支持 null。
gawk -v RS='\0' -v ORS='\0' 'NR <= 2 {print}'
这可以缩短,gawk -v RS='\0' -v ORS='\0' 'NR <= 2'
因为打印记录是默认操作。
对于大文件,最好在第二行之后退出。
gawk -v RS='\0' -v ORS='\0' 'NR==3 {exit} {print}'
或者,您可以使用head
.无法选择使用空字节而不是换行符作为记录分隔符,但您可以交换这两个字符,调用head
,然后交换回来。
tr '\0\n' '\n\0' | head -n 2 | tr '\0\n' '\n\0'