Awk

修剪 CSV 文件中的路徑名

  • February 14, 2022

我正在為一個過濾器苦苦掙扎,在該過濾器中,我試圖在第 3 次或第 n 次出現字元後修剪 CSV 的特定列中的數據\

我的數據看起來像這樣:

data,data,c:\path1\folder2\folder3\folder4\...,data,data,data
data,data,c:\path1\folder2\folder3\folder4\...,data,data,data
data,data,c:\path1\folder2\folder3\folder4\...,data,data,data
data,data,c:\path1\folder2\folder3\folder4\...,data,data,data

我希望過濾器產生:

data,data,c:\path1\folder2\folder3\,data,data,data

第 3 列包含文件路徑,它可能位於從一個文件夾到多個文件夾的任何位置。我希望最多有 3 個文件夾。

我不想刪除其他剩餘的列,但要編輯文件。

我一直在嘗試使用awk,sed並嘗試將cut命令組合cut -f1-4 -d '\'成一個awk語句,但我一生都無法讓它發揮作用。

使用 GNU awk 進行 gensub():

$ awk -v n=3 'BEGIN{FS=OFS=","} {$3=gensub("(([^\\\\]*\\\\){"n+1"}).*","\\1",1,$3)} 1' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data

或使用任何 awk:

$ awk -v n=3 'BEGIN{FS=OFS=","} match($3,"(([^\\\\]*\\\\){"n+1"})"){$3=substr($3,1,RLENGTH)} 1' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data

使用sed,假設沒有其他更早的欄位包含由四個反斜杠分隔的字元串:

$ sed 's/\(\([^,\]\{1,\}[\]\)\{4\}\)[^,]*/\1/' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data

或者,使用擴展的正則表達式,

$ sed -E 's/(([^,\]+[\]){4})[^,]*/\1/' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data

這裡使用的sed表達式是一個替換,被替換的文本是任何匹配的內容(([^,\]+[\]){4})[^,]*。此正則表達式匹配並擷取四個以反斜杠分隔的非空字元串 ( ([^,\]+[\]){4})。這被擷取以在替換字元串中重複使用,但是直到並包括下一個逗號(與尾隨匹配的任何內容[^,]*)的所有內容都將被丟棄。

替換文本是\1,它插入這四位反斜杠分隔的字元串。


您顯然也可以這樣做cutpaste但請注意,以下命令管道會讀取文件三次,並且還會在第三個欄位的路徑名上刪除最後的反斜杠:

$ paste -d , <( cut -d , -f -2 file ) <( cut -d , -f 3 file | cut -d '\' -f -4 ) <( cut -d , -f 5- file )
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data

您可以通過將前兩個欄位視為第三個欄位中路徑名的一部分來擺脫第cut一個欄位,但這仍然會讀取文件兩次:

$ paste -d , <( cut -d '\' -f -4 file ) <( cut -d , -f 5- file )
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data

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