Text-Processing
替換具有循環結構的第一列的內容
我有一個要更改第一列的文件,例如,我有以下文件(在原始文件中,我有多個列,但將以下內容截斷為 2 列,文件末尾可能有空行)。
測試.txt:
0 a 2 b 3 c 4 d 5 e
我需要將第一列的內容從 0 -> 2, 2 -> 3 , 3 -> 5 , 4 -> 0, 5 -> 4 更改為我的最終文件,
2 a 3 b 5 c 0 d 4 e
我嘗試使用 awk 如下,
awk '$1=="0"{$1="2"} $1=="2"{$1="3"} $1=="3"{$1="5"} $1=="4"{$1="0"} $1=="5"{$1="4"};1' test.txt
但是由於 awk 不會逐行讀取並更改所需的內容,因此輸出是,
4 a 4 b 4 c 0 d 4 e
任何人都可以幫助我轉換為我需要的東西,python、sed 或 awk,或者歡迎任何腳本工具。
AWK實際上是逐行讀取的,你只需要
next
在列印後為每個賦值添加語句,因此將跳過其餘程式碼。awk '$1=="0"{ $1="2"; print; next } $1=="2"{ $1="3"; print; next } $1=="3"{ $1="5"; print; next } $1=="4"{ $1="0"; print; next } $1=="5"{ $1="4"; print; next }1' infile
或者使用控制標誌:
awk '!s && $1=="0"{ $1="2"; s=1 } !s && $1=="2"{ $1="3"; s=1 } !s && $1=="3"{ $1="5"; s=1 } !s && $1=="4"{ $1="0"; s=1 } !s && $1=="5"{ $1="4"; s=1 } { print; s=0 }' infile
但您也可以按以下方式完成所有操作:
awk -F'( )' 'BEGIN{ split("2 1 3 5 0 4", map) } $1!=""{ $1=($1+1 in map)?map[$1+1]:$1 }1' infile
使用split(string, arryName) 函式,我們創建了一個數組
map
,其索引和值如下所示,基於 FS 進行拆分(預設為空格/製表符)Index Value map[<0>+1] --> 2 map[<1>+1] --> we choice it 1 so it will be unchanged for <1> --> 1 map[<2>+1] --> 3 map[<3>+1] --> 5 map[<4>+1] --> 0 map[<5>+1] --> 4
<#>
角度內的數字是來自第一列的值,並且由於 awk 中數組的索引從 1 而不是 0 開始,所以我們將列值加一,然後從映射數組中獲取相應的值。作為通用解決方案(但我仍然會使用上述一個,因為幾乎使用者定義的鍵/值是順序的,並且數組索引可以用作鍵,但是)如果不是這樣,你就去吧:
awk -F'( )' 'BEGIN{ len=split("0 2 2 3 3 5 4 0 5 4", map) } { for(i=1; i<=len/2; i+=2 ) if($1==map[i]){ $1=map[i+1]; break} }1' infile