我有一个大文本文件(666000 列),格式为
A B C D E F
所需输出
AB CD EF
我们怎样才能在sed
or中做到这一点awk
?我尝试了几件事,但似乎没有任何效果。请建议一些东西。
答案1
在sed
:
sed 's! \([^ ]\+\)\( \|$\)!\1 !g' your_file
这将进行替换并将结果打印到标准输出。要就地修改文件,请添加-i
开关:
sed -i 's! \([^ ]\+\)\( \|$\)!\1 !g' your_file
解释
此sed
命令将查找一个空格,后跟至少一个非空格字符,最后跟一个空格或行尾。它用它找到的任何非空格字符替换该序列,后跟一个空格。由于g
修饰符是在末尾提供的,因此替换会在整行中应用尽可能多次(这称为全局替换) 。因此,基本上,对于像这样的序列A B C
,sed
将找到模式“B”并将其替换为“B”,留下AB C
最终结果。
此代码所做的假设
例如,此代码假设列之间的空格实际上是空格而不是制表符。这可以很容易地解决,但会牺牲可读性:
sed 's![[:blank:]]\+\([^[:blank:]]\+\)\([[:blank:]]\+\|$\)!\1 !g' your_file
答案2
awk:
awk '{printf $1$2;for(i=3; i<=NF;i+=2){printf " %s",$i$(i+1)}print}' file
对于大文件来说,这可能是两者中最快的。
珀尔:
perl -pe 's/([^\s]+)\s+([^\s]+)/$1$2/g' file
答案3
RS
如果您的文件确实有那么多列,一种选择是使用 gawk 通过设置“一个或多个空白字符”将每一列视为一条记录。这有助于避免在列中设置循环。请注意,面对一行中的奇数列,此解决方案很脆弱。
awk --re-interval -v RS='[[:space:]]{1,}' '{x=$0; getline; printf x$0RT}' file