如何將文件中出現在特定模式之間的行截斷為特定長度?

如何將文件中出現在特定模式之間的行截斷為特定長度?

我有多個文件,其中我必須只截斷模式@TEST 和enabled="true"> 之間的行。當存在匹配時,@TEST和之間的字串enabled="true">應該只有 50 個字元。所有其他線路應保持不變。

例子:

@TEST-TC_0010 @TEST 驗證 RADIUS 計費伺服器在從 RADIUS 用戶端接收到計費請求封包時不應發送計費回應訊息"enabled="true">

我必須更改上面的行,如下所示。

@測試-TC_0010@測試驗證 RADIUS 計費伺服器不應啟用=“真”>

答案1

在這種情況下,您可以將 grep 與 Perl 環視結合使用。

grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile

表達式「(?<=)」標記符合開始的點,表達式「(?=)」標記符合結束的點。

「.*」告訴 grep 返回開始點和結束點之間的所有內容。

使用您的測試輸入,上面的行會傳回 157 個字元。

$ echo "Verify that the RADIUS accounting server should not send the Accounting-Response Message on Receiving the Accounting-Request Packet from the RADIUS Client" | wc -m
157

如果您想進一步截斷為僅前 50 個字符,您可以使用 cut

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50
Verify that the RADIUS accounting server should no

如果您希望將結果儲存到檔案中,則需要將輸出透過管道傳輸到另一個檔案。你可以使用類似下面的東西...

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50 >> outputfile

我個人不建議覆蓋輸入文件,因為您可能在某些時候需要使用原始資料。

因此,如果您需要保留文件中的所有其他條目並僅截斷啟用=“true”的行,我們需要將工具更改為 awk。

$ awk  -F'@TEST' '{if (/true/) print substr($3,2,50); else print $0}' inputfile >> outputfile

此 oneliner 將不做任何更改地輸出與 true 不匹配的每一行。當 true 匹配時,該行將截斷為 50 個字元。我再次建議不要覆蓋原始數據,以便將結果透過管道傳輸到輸出檔案中。

根據 OP 對問題所做的最新編輯,我修改了 awk 單行語句以複製 Beginner 提供的輸出。他在評論中提到 awk 不起作用。在 OP 提供有關 awk 為何不起作用的更多詳細資訊之前,當在 Ubuntu 16.04 上使用 awk 4.1.3 時,以下行將返回他迄今為止詳細說明的結果。

awk  -F'@TEST' '{if (/true/) print "@TEST"$2,"@TEST",substr($3,2,50),"enabled=\"true\">"; else print $0}' inputfile >> outputfile

相關內容