我有一个文件f1.txt
:
ID Name
1 a
2 b
3 g
6 f
空格数为不是固定的。仅使用一个空格替换所有空格的最佳方法是什么tr
?
这是我到目前为止所拥有的:
cat f1.txt | tr -d " "
但输出是:
IDName
1a
2b
3g
6f
但我希望它看起来像这样:
ID Name
1 a
2 b
3 g
6 f
请尽量避免sed
。
答案1
与tr
,使用s
挤压重复选项:
$ tr -s " " < file
ID Name
1 a
2 b
3 g
6 f
或者你可以使用一个awk
解决方案:
$ awk '{$2=$2};1' file
ID Name
1 a
2 b
3 g
6 f
当您更改记录中的字段时,awk
重建$0
会获取所有字段并将它们连接在一起,并用 分隔OFS
,默认情况下是空格。
这会将空格和制表符序列(以及可能的其他空白字符,具体取决于 的区域设置和实现awk
)压缩到一个空格中,同时还会删除每一行的前导和尾随空白。
答案2
答案3
如果你想压缩“空白”,你需要使用 tr 的预定义字符集“:blank:”(水平空白制表符和空格)或“:space:”(垂直空白):
/bin/echo -e "val1\t\tval2 val3" | tr -s "[:blank:]"
示例在 Red Hat 5 (GNU tr) 上运行。
就我而言,我想将所有空白标准化为单个空格,这样我就可以依靠空格作为分隔符。
正如 dastrobu 的第二条评论所指出的,我错过了手册页中的措辞:
-s uses the last specified SET, and occurs after translation or deletion.
这使我们能够消除第一个 tr。面对我的笨拙,工藤实在是太没耐心了。
之前,从 Redis 配置中解析端口。文件:
grep "^port" $redisconf | tr "[:blank:]" " " | tr -s "[:blank:]" | cut -d" " -f2
之后,通过挤压指定 SET2:
grep "^port" $redisconf | tr -s "[:blank:]" " " | cut -d" " -f2
输出:
6379
演示当涉及属于 [:blank:] 字符类的连续混合字符时,单独挤压会失败:
/usr/bin/printf '%s \t %s' id myname | tr -s "[:blank:]" | od -cb
0000000 i d \t m y n a m e
151 144 040 011 040 155 171 156 141 155 145
0000013
注意:我的 printf 格式的两个字符串字段由 1 个空格、1 个制表符、1 个空格分隔。挤压后该序列仍然存在。在八进制转储的输出中,这由 ascii 序列 040 011 040 表示。
答案4
这是一个老问题,已经解决过很多次了。只是为了完整性:我有一个类似的问题,但想通过管道将线路传递到另一个程序。我用了参数。
-L max-lines
Use at most max-lines nonblank input lines per command line.
Trailing blanks cause an input line to be logically continued
on the next input line. Implies -x.
所以cat f1.txt | xargs -L1
似乎输出正是你想要的。