bash - 在bash中,正規表達式 從變數中提取除最後一個欄位之外的所有欄位

  显示原文与译文双语对照的内容
100 1

我有一個與這裡類似的文件:

01/01 THIS IS A DESCRIPTION 123.45
12/23 SHORTER DESC 9.00
11/16 DESC 1,234.00

三個欄位,日期,說明,金額。第一個欄位後面總是有空格。最後一個欄位總是前面有一個空格。但中間的區域通常包含空間。

我知道 bash/正規表達式 很好地獲得了第一個和最後一個欄位( 例如 echo ${LINE##* } 或者剪切 -f1 -d ) 。但是我怎樣才能得到中間的?除了第一個和最後一個欄位以外的所有內容。

时间:原作者:0个回答

58 2

如果要刪除第一個和最後一個欄位,你可以擴展引用的參數擴展技術:

var=${var#* } var=${var% *}

單個 # 或者 % 刪除與全局匹配的最短子字元串。

原作者:
128 2

你可以使用 awk 嘗試以下操作:

awk '{$1="";$NF=""}1' file_name

請讓我知道這是否有幫助。

原作者:
52 0

bash: 把行讀成單詞的array,從 array 中挑選出想要的元素

while read -ra words; do 
 date=${words[0]}
 amount=${words[-1]}
 description=${words[*]:1:${#words[@]}-2}
 printf"%s=%sn" date"$date" desc"$description" amt"$amount"
done <file

輸出

date=01/01
desc=THIS IS A DESCRIPTION
amt=123.45
date=12/23
desc=SHORTER DESC
amt=9.00
date=11/16
desc=DESC
amt=1,234.00

這就是有趣的部分:${words[*]:1:${#words[@]}-2}

  • 為例,從索引 1 slice index ( 2nd 元素) length length length elements elements elements elements elements elements"
  • 這些單詞將被加入一個帶有空格分隔符的單個字元串中。

請參見 shell 參數擴展插件,並向下滾動以進行討論。

如果你想在bash中使用 正規表達式,那麼你可以使用捕獲括弧和 BASH_REMATCH array

while IFS= read -r line; do 
 if [[ $line =~ ([^[:blank:]]+)""(.+)""([^[:blank:]]+) ]]; then 
 echo"date=${BASH_REMATCH[1]}" 
 echo"desc=${BASH_REMATCH[2]}" 
 echo"amt=${BASH_REMATCH[3]}"
 fi
done <file

上述輸出相同。

注意在 Pattern 中需要引用空格( 或者反斜杠轉義)

原作者:
144 4

你可以使用 sed 進行以下操作:

$ sed -E 's/^[^[:space:]]*[[:space:]](.*)[[:space:]][^[:space:]]*$/1/' file
THIS IS A DESCRIPTION
SHORTER DESC
DESC

你還可以使用 cutrev 刪除第一個和最後一個欄位:

$ cut -d ' ' -f2- file | rev | cut -d ' ' -f2- | rev
THIS IS A DESCRIPTION
SHORTER DESC
DESC

或者 GNU grep:

$ grep -oP '^H+hK(.*)(?=h+H+$)' file
THIS IS A DESCRIPTION
SHORTER DESC
DESC

或者,使用Bash循環和參數擴展插件:

$ while read -r line; do line="${line#* }"; line="${line% *}"; echo"$line"; done <file
# same output
原作者:
...