Text-Processing
如何將 CR 分隔的字元串拆分為多行並將 id 附加到每個新行?
我有一個文件,其中的行由內部輸入符分區,如下所示:
EMP|123|10 **\r**資訊|約翰|史密斯|M|01/12/1980 **\r**地址|125|BRIDGE RD|哥倫布|OH EMP|456|10 **\r**資訊|大衛|PIRT|M|02/12/1980 **\r**地址|257|BRIDGE RD|哥倫布|OH EMP|789|10 **\r**資訊|JENN|MCKENZI|F|03/12/1980 **\r**地址|389|BRIDGE RD|哥倫布|OH
請注意,CR 之間的行部分進一步由
|
字元分隔。我想在 CR 字元處將每一行分成單獨的行。然後每個新行(即,通過用換行符替換 CR 形成的行)應該
|
從原始行的 Id(第二個分隔欄位)開始。預期輸出:
EMP|123|10 123|INFO|JOHN|SMITH|M|01/12/1980 123|ADDR|125|BRIDGE RD|COLUMBUS|OH EMP|456|10 456|INFO|DAVID|PIRT|M|02/12/1980 456|ADDR|257|BRIDGE RD|COLUMBUS|OH EMP|789|10 789|INFO|JENN|MCKENZI|F|03/12/1980 789|ADDR|389|BRIDGE RD|COLUMBUS|OH
Id 是重複的,因此我們可以知道輸出中的每組三行屬於同一(一個)輸入行。
我嘗試了以下命令,但它只用換行符替換了 CR;我不確定如何將 Id 附加到新行
tr '\r' '\n' < test.txt > new.txt
輸出:
EMP|123|10 INFO|JOHN|SMITH|M|01/12/1980 ADDR|125|BRIDGE RD|COLUMBUS|OH EMP|456|10 INFO|DAVID|PIRT|M|02/12/1980 ADDR|257|BRIDGE RD|COLUMBUS|OH EMP|789|10 INFO|JENN|MCKENZI|F|03/12/1980 ADDR|389|BRIDGE RD|COLUMBUS|OH
我怎樣才能做到這一點?
怎麼樣
$ awk -F '\r' '{ print $1; split($1,a,"|"); for(i=2;i<=NF;i++) print a[2] "|" $i; }' file EMP|123|10 123|INFO|JOHN|SMITH|M|01/12/1980 123|ADDR|125|BRIDGE RD|COLUMBUS|OH EMP|456|10 456|INFO|DAVID|PIRT|M|02/12/1980 456|ADDR|257|BRIDGE RD|COLUMBUS|OH EMP|789|10 789|INFO|JENN|MCKENZI|F|03/12/1980 789|ADDR|389|BRIDGE RD|COLUMBUS|OH
在 sed 中:
sed ':loop; s/^\([^|]*|\)\([^|]*|\)\([^\r]*\)\r/\1\2\3\n\2/; t loop'
這是一個(有點)簡單的替換:匹配一個由所有字元組成的模式(即直到並包括)
\r
緩衝區中的第一個字元。將其分為三個擷取組:
- 所有通過(即直到並包括)
|
緩衝區中的第一個。這將EMP|
適用於文件中的每一行。- 之後的所有內容,通過(即直到並包括)
|
緩衝區中的下一個(即第二個)。這將是123|
,456|
或789|
在您的文件中。- 之後的所有內容,直到(但不包括)
\r
緩衝區中的第一個。然後它將上面替換為
- 三個擷取組(
\1\2\3
);即,直到(但不包括)\r
緩衝區中的第一個,- 換行符,和
- 第二個擷取組(
\2
);即 id 和|
.然後緩衝區的其餘部分(緩衝區中第一個之後
\r
的所有內容)保留在原位,因此它落在新創建的行上重複的 id 之後。然後,如果上面的 match 和ssubstitute成功(
t
is test and goto if success),回去再試一次。對初學者來說可能不明顯的一個方面是,即使我們使用s替換命令 將換行符
\n
插入緩衝區 ,從而創建了一個新行,仍然在整個緩衝區上執行(包括內部/嵌入的換行符)字元)而不僅僅是“換行符”(即換行符之後的部分)。所以, 讀第一行,sed``sed
EMP|123|10\rINFO|JOHN|SMITH|M|01/12/1980\rADDR|125|BRIDGE RD|COLUMBUS|OH
進入緩衝區。
s
第一次執行命令後,緩衝區包含EMP|123|10 123|INFO|JOHN|SMITH|M|01/12/1980\rADDR|125|BRIDGE RD|COLUMBUS|OH
所以
s
命令的下一次迭代匹配
\1
=EMP|
,\2
=123|
, 和\3
=10 123|INFO|JOHN|SMITH|M|01/12/1980
(包括在第一次迭代中插入的換行符)。警告:如果輸入行中
\r
的第二個之前有 a,這可能會造成混亂 。|