一、問題描述
最近需要利用Shell將多行多列文字中某一列,透過指定的分隔符合併成一行。假設需要處理的文字如下:
我們主要處理的是,將使用者名稱提取處理,合併成一行,並透過逗號進行分隔。最終的格式如下:
“li1”,”huan”,”wang”,”wu”,”78c”,”zh”,”liu”,”zhao”,”xu”,”yang”
二、解決方案
首先是提取每一行的第X列,我最先能夠想到的是awk命令,如下
awk '{print $2}' user1.txt
1
2
效果如下:
接著,是不是可以把替換符替換為逗號呢?
使用tr命令
awk '{print $2}' user1.txt |tr "\n" ","
1
效果:
看著好像是很接近,我們將上面的 , 分隔改為”,”分隔,是不是就okey了呢?命令如下:
awk '{print $2}' user1.txt |tr "\n" "\",\""
1
只是很遺憾,執行效果如下:
為什麼呢?
因為tr是單個字元處理工具,而不是字串處理工具。
既然tr不可以替換字串,那麼咱們就用sed命令。因為sed命令不僅僅可以處理字元,還可以處理字串。
先來個簡單的,將換行替換成逗號,命令如下:
awk '{print $2}' user1.txt |sed 's/\n/,/g'
1
執行結果如下:
好吧,竟然不聽話。為什麼呢?
因為sed命令處理過程是:從文字流中讀取一行文字後,先把換行符去掉,然後進行相應的命令,處理完後再新增上換行符。這就導致sed命令,無法對換行符進行直接替換。
既然這樣行不通,怎麼搞呢?
解決方案一:
既然sed不能修改換行符,那就是在使用sed之前,把換行符幹掉。幹掉換行符,可以使用tr和xargs命令。
#使用xargs命令幹掉換行符
awk '{print $2}' user1.txt |xargs
#使用tr命令幹掉換行符
awk '{print $2}' user1.txt |tr "\n" " "
1
2
3
4
使用sed命令將空格替換成”,”,命令如下:
awk '{print $2}' user1.txt |xargs |sed 's/ /","/g'
1
但是開頭和結尾少了一個雙引號,解決方案如下:
echo '"'`awk '{print $2}' user1.txt |xargs |sed 's/ /","/g'`'"'
1
2
解決方案二:
echo '"'`awk '{print $2}' user1.txt | sed ':label;N;s/\n/","/;b label'`'"'
1
更多內容,可以點選這裡:http://www.findme.wang/blog/detail/id/310.html