利用shell中awk和xargs以及sed將多行多列文字中某一列合併成一行

牧之丨發表於2024-06-15

一、問題描述
最近需要利用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

相關文章