使用制表符替换除第一个空格以外

时间:2016-02-26 19:59:33

标签: macos bash replace

我有一系列管道bash命令

grep A01929 test_FTF89MNR.txt |
    grep status |
    tr "=" " " |
    tr "," " " |
    cut -d" " -f 1 -f 2 -f 11 -f 14 -f 17

产生一大堆输出,看起来像这样

...    
2016-02-25 09:15:01.41 2742 1535 1796
...

为了便于导入Excel,我想用TABS 替换列之间的所有空格,除了分隔数据和时间的第一个空格。所以目标输出将是

...    
2016-02-25 09:15:01.41\t2742\t1535\t1796
...

是否有一个简单的命令行fu,我可以在我的管道链上实现这一目标? tr似乎没有允许它做范围的东西。我在OS X上。

5 个答案:

答案 0 :(得分:4)

您可以使用awk来准确指定分隔符。

awk '{print $1 " " $2 "\t" $3 "\t" $4 "\t" $5}' Input.txt

答案 1 :(得分:1)

您可以在sed中使用以下技巧:首先用制表符替换所有空格,然后替换一个空格。以下是一个示例:

echo "a b c d" | sed 's/ /:/g;s/:/ /'

第一个sed命令s/ /:/g全局替换(因此g)所有空格冒号,第二个命令用空格替换第一个冒号。这会将字符串a b c d转换为a b:c:d

答案 2 :(得分:1)

使用sed变得可爱可以帮助你 - 将它们全部替换掉​​,然后替换第一个背面,例如

sed 's/ /\t/g; s/\t/ /1'

e.g。

$ echo "2016-02-25 09:15:01.41 2742 1535 1796" | sed 's/ /\t/g; s/\t/ /1' 2016-02-25 09:15:01.41 2742 1535 1796

正如评论中指出的那样,这是mac,因此不会起作用。 ħere's a link to how to handle tabs on mac though.

或者,这是一个替换所有管道的所有AWK版本。 awk '$0 ~ /A01929/ && $0~/status/ {gsub("=",""); gsub(",",""); print $1 " " $2 "\t" $11 "\t" $14 "\t" $17}' test_FTF89MNR.txt

匹配一行上的grepped值,然后匹配替换,并且=什么都不匹配,然后打印所需的分隔符。

答案 3 :(得分:1)

要扩展Merlin提供的建议awk的答案,您可以将cut替换为awk,而不是进行额外的后期处理。您可以将tr的两个来电替换为一个:

grep A01929 test_FTF89MNR.txt |
    grep status |
    tr "=," " " |
    awk '{print $1 " " $2 "\t" $11 "\t" $14 "\t" $17}'

根据原始文件的摘录,我确信有人可以提出全部版本awk

答案 4 :(得分:0)

如果您有固定的字段数据,则可以在Bash中使用read循环:

txt="2016-02-25 09:15:01.41 2742 1535 1796" 

while read -r da ti f1 f2 f3
do 
    printf "%s %s\t%s\t%s\t%s" $da $ti $f1 $f2 $f3
done <<< $txt