Bash

bash: /bin/sed: 參數列表太長

  • January 9, 2021

我有兩個文件。第一個(電子郵件)應根據第二個(域)進行清理。第一個是 15 GB,第二個是 160 MB。

dom=`cat file2.txt | xargs | sed -e "s/ /|/g"` ; sed -r "/$dom/d" file1.txt >> final_file.txt

這個命令給了我bash: /bin/sed: Argument list too long.

聽起來你只是想要:

grep -Fvf file2.txt file1.txt > final_file.txt

那是儲存在不包含任何行的行final_file.txt中。file1.txt``file2.txt

如果您-x希望該行file1.txt不在file2.txt. 或-w匹配單詞(例如 wherebar.com不會匹配foobar.comor bar.common,但仍會匹配 in foo.bar.com.us)。

但是,如果我們要尋找千兆字節的數據和兆字節的不同字元串,即使這樣也需要很長時間。

使用類似 shell 或支持程序替換的更快ksh方法是zshbash

export LC_ALL=C
comm -23 <(sort file1.txt) <(sort file2.txt) > final_file.txt

現在,如果正如您在評論中澄清的那樣,file2.txt它是一個域列表,並且您的意思是過濾掉以任何這些域file1.txt結尾的行@,那麼更有效的方法是使用雜湊表:

awk -F@ '
 ! domains_processed {excluded[$0]; next}
 ! ($NF in excluded)
 ' file2.txt domains_processed=1 file1.txt > final_file.txt

您的方法存在問題:

  • 無用使用cat(UUOC)。cat是連接文件。對於單個文件來說意義不大。您可以使用xargs < fileor < file xargsfor xargsstdin 直接作為文件,而不是來自cat僅推送文件內容的程序的管道。
  • xargs預設呼叫echo。雖然echo將其參數與您想要的空格字元連接起來,但它還執行其他操作,其列表取決於實現。還xargs期望以非常特定的格式輸入。在這裡,我希望您希望將 的每一行file2.txt作為單獨的參數傳遞echo,您需要 GNU 特定的xargs -rd '\n'. 也xargs將根據需要執行echo多次以避免參數大小的限制。因此,xargs對於 160MB 的輸入,輸出將有幾行。

要使用特定字元連接文件的行,命令是paste

paste -sd '|' file2.txt
  • sed -r在這裡,通過將這些單詞與 連接起來,您正在為(-r作為 GNU 擴展)建構一個正則表達式|,但您並沒有轉義在這些行中找到的正則表達式運算符。如果這些是域名,請注意這.是一個匹配任何字元的正則表達式運算符。你對其他角色會有更大的問題。如果您無法完全sed "/$dom/r"控制.file2.txt
  • 如果file2.txt是 160MB 大,那麼$dom(或多或少)也會如此。命令行的大小是有限的。在 Linux 上,單個參數的大小也受到限制(最大為 128KiB),因此您sed不能通過參數傳遞腳本。它必須通過-f.

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