Bash
bash: /bin/sed: 參數列表太長
我有兩個文件。第一個(電子郵件)應根據第二個(域)進行清理。第一個是 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.com
orbar.common
,但仍會匹配 infoo.bar.com.us
)。但是,如果我們要尋找千兆字節的數據和兆字節的不同字元串,即使這樣也需要很長時間。
使用類似 shell 或支持程序替換的更快
ksh
方法是zsh
:bash
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 < file
or< file xargs
forxargs
stdin 直接作為文件,而不是來自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
.