Bash

在 sed 中重命名以允許在替換之前進行進一步匹配

  • May 23, 2020

我試圖重命名 fileA 中的文本,使用sed. 倒數第二列fileA是產品名稱的完整描述所在的位置。我想用它的 ID 替換產品名稱。但是,描述中的某些文本具有相似的內容(範例如fileA)。在第 2 行和第 4 行中出現了兩次“橙汁”。

我正在生成renamefilesed. 但是,sed將找到的每個“橙汁”替換為“3071”,而不管“橙汁”匹配後是否出現“帶果肉”。

文件A:

AB12345    100    0    Apple juice 20/05   AB
CD67890    150    0    Orange juice with pulp 22/05   CS
EF25879    100    0    Watermelon juice 19/05   CG
GH96314    98    0    Orange juice 20/05   PU
IJ74123    95    0    Strawberry juice with lemon 17/05   ST

重新命名文件:

s/\<Apple juice\>/3071/g
s/\<Orange juice with pulp\>/3072/g
s/\<Orange juice\>/3073/g
s/\<Watermelon juice\>/3074/g
s/\<Apple juice with lemon\>/3075/g
s/\<Strawberry juice with lemon\>/3076/g

電流輸出:

AB12345    100    0    3071 20/05   AB
CD67890    150    0    **3073** 22/05   CS
EF25879    100    0    3074 19/05   CG
GH96314    98    0    3073 20/05   PU
IJ74123    95    0    3076 17/05   ST

所需的輸出:

AB12345    100    0    3071 20/05   AB
CD67890    150    0    3072 22/05   CS
EF25879    100    0    3074 19/05   CG
GH96314    98    0    3073 20/05   PU
IJ74123    95    0    3076 17/05   ST

我正在使用“<>”,因為在某處發現它僅在完全匹配時才有助於替換。但是,在這種情況下它似乎不起作用。(錯誤在目前輸出中以粗體顯示。)

有沒有更好或更有效的方法來確保字元串替換在前兩個字元串匹配後考慮更多的單詞並用它們的 ID 替換這些名稱?

如果我不夠清楚,請告訴我。謝謝!

renamefile需要根據長度重新排序,首先替換較長的名稱

awk '{ print length, $0 }' renamefile| sort -nr | cut -d" " -f2- &gt; renamefile2

輸出

s/\&lt;Strawberry juice with lemon\&gt;/3076/g
s/\&lt;Orange juice with pulp\&gt;/3072/g
s/\&lt;Apple juice with lemon\&gt;/3075/g
s/\&lt;Watermelon juice\&gt;/3074/g
s/\&lt;Orange juice\&gt;/3073/g
s/\&lt;Apple juice\&gt;/3071/g

然後你可以毫無問題地申請

sed -f renamefile2 fileA

描述:

awk循環線

  • length是awk的內置函式。當不帶參數呼叫時,它將列印目前行的大小(更多資訊在awk length
  • $0目前行

以下命令將在行本身旁邊列印每行的長度

awk '{ print length, $0 }' renamefile

24 s/\&lt;Apple juice\&gt;/3071/g
35 s/\&lt;Orange juice with pulp\&gt;/3072/g
25 s/\&lt;Orange juice\&gt;/3073/g

sort將對輸入文本進行排序

  • -n將按數字排序
  • -r反轉結果,使其下降。

cut將選擇文本的一部分(因為我們不想要最終腳本中的長度,只需要選擇sed部分行)

  • -d" "指定space此處的分隔符。
  • -f2-從欄位 2 到行尾

引用自:https://unix.stackexchange.com/questions/588379