用 sed 指令取代長字串:參數列表太長錯誤

用 sed 指令取代長字串:參數列表太長錯誤

我正在嘗試執行這個命令

sed -i -e "s/BASE_64/$BASE_64/" FILE_NAME

其中$BASE_64是文件內容的 Base 64 表示形式。

sed由於字串太長,給我一個錯誤。

參數列表太長

如何才能避免這個錯誤呢?

答案1

你總是可以這樣做(因為你sed已經在使用 GNU ( -i)):

sed -i -f - FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF

-f -告訴sed從 stdin 讀取 sed 腳本。

如果您想在 Linux(且僅限 Linux)上對多個文件重用相同的腳本,請使用類似於 的 shell zsh,版本高達 5.0 kshbash它使用臨時文件實現此處文檔(而不是像dashor yash(或bash5.1+)這樣的管道相對較小的heredocs並且仍然使用GNU sed,你可以這樣做:

find . -name '*.conf' -exec sed -i -f /dev/stdin {} + << EOF
s/BASE_64/$BASE_64/g
EOF

在 Linux 上(僅限 Linux 和 Cygwin),/dev/stdin並不意味著標準輸入以同樣的方式-。相反,它是指向在標準輸入上打開的文件的符號鏈接,因此每次sed打開它時,它都會從頭開始重新打開該文件。上面的命令在其他系統(具有/dev/stdin)或使用通過管道實現此處文檔的 shell 上可以正常工作,但前提是只有足夠少的conf文件sed僅被調用一次。當第二次呼叫時,在非 Linux/Cygwin 系統上,如 with -f -/dev/stdin將顯示為空,因為它已被第一次呼叫讀取。

busybox sed-i也以與 GNU 相同的方式支持sed,但不支持-f -.所以-f /dev/stdin無論如何你都想使用那裡。對於 FreeBSD sed,使用:

sed -i '' -f /dev/stdin FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF

答案2

首先,將 Base64 編碼的資料保存在名為base64.txt.

例如:

base64 < originalfile > base64.txt

然後:

printf '%s\n' '/BASE64/r base64.txt' 1 '/BASE64/d' w | ed FILENAME

這用於ed搜尋FILENAME包含字串的行BASE64,在該行之後插入內容base64.txt,返回到第一行,然後BASE64再次搜尋包含字串的行並將其刪除。該w命令ed保存修改後的檔案。

答案3

另一種選擇是將命令替換seded並將命令儲存在檔案中。例如,如果您ed_cmds使用以下內容建立:

%s/BASE_64/<expanded variable>/g
w
q

然後你可以運行

< ed_cmds ed FILE_NAME

它會進行您想要的更改,因此$BASE_64您無需進行設置,而是建立 ed 命令檔。

艾德解釋

  • %表示將命令應用於檔案的每一行
  • s/pat1/pat2/g在末尾替換出現的pat1pat2使其對線路上的每場比賽都執行此操作,而不僅僅是第一個g
  • w將更改寫入磁碟
  • qquit (無論如何,當它得到 EOF 時就會發生)

當然,您也可以將sed命令放入文件中並使用-f,但如果您這樣做並且想要就地修改文件,您最好使用ed而不是建立臨時文件並移動它sed -i

答案4

我最終將sed說明放入文件中

SEDCOMMANDS=`tempfile`

並打電話給

sed -f "$SEDCOMMANDS" -- "$FILE_NAME"

如果你不使用的話也很好sed -i。如果您想就地編輯文件,請按照https://unix.stackexchange.com/a/284188/149867並將等效ed指令放入檔案中,後跟wq

相關內容