Bash

使用 sed 將字元串模式替換為序列

  • July 15, 2019

我想用 1 2 3 4 5 6 7 之類的數字序列替換文本文件中的字元串,最好使用 sed。

這是我嘗試過的(沒有搜尋字元串)並且似乎有效:

for i in {1..5};do echo $(seq 1 $i); done

輸出:

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5

但是,當我嘗試這個時:

for i in {1..5};do sed -i "s/abc/$(seq 1 $i)/g" test; done

我收到以下錯誤:

sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command

我也嘗試將替換字元串括在括號中,但它似乎不起作用。

第一個循環

for i in {1..5}

將被替換為文件名的 glob,我想在其中替換一些參數。

TL; 博士:

有一些方法可以解決這個問題,我認為最適合您的範例案例的是:

for i in {1..5};do sed -i "s/abc/$(seq -s ' ' 1 $i)/g" test; done

即:我們要求seq使用一個空格來分隔每個數字。

解釋:

你得到這些錯誤的原因是因為輸出來自:

seq 1 5

不是:

1 2 3 4 5

反而:

1
2
3
4
5

並且由於您將$(seq 1 $i) 命令替換包含在雙引號中,因此不會執行通常的分,因此該實用程序輸出的所有換行符(最後一個換行符除外)seq都保持原樣。

因此實際的sed 命令變成了:

sed -i "s/abc/1
2
3
4
5
/g" test

這是不被接受的,因為就sed 目前而言,您向它提供了一個s/abc/1命令,即缺少所需的 final /

Anecho $(seq 1 5)確實會列印1 2 3 4 5,因為$(seq 1 5)它不在雙引號內,因此按照 shell 的預設行為進行分詞。

我們確實可能會修復您的範例案例,如下所示:

for i in {1..5};do sed -i "s/abc/$(echo $(seq 1 $i))/g" test; done

也就是說,通過另一個命令替換(那個)中執行命令替換(你原來的seq 1 $i)。echo

這甚至在雙引號內也有效,因為$(echo ...)命令替換是在一個處於“I-am-inside-a-double-quote”狀態的子shell中執行的,因此在那裡執行輸出的字拆分。seq

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