簡體   English   中英

從外殼清理文件

[英]Scrubbing files from the shell

我的shell技能有些生銹,但是我想做的是獲取2個文件,並根據匹配字段從另一個文件中“清理”一個文件。 這是重要的部分,其余各行可以有所不同,但是如果關鍵字段匹配,它將被刪除。 例如,我的文件用豎線分隔,第二個字段是關鍵字段。

File 1
------
acme|widg001|green|plant a|<timestamp>
acme|widg102|blue|plant b|<timestamp>
acme|widg002|yellow|plant a|<timestamp

File 2
------
acme|widg001|blue|plant a|<timestamp>
acme|widg701|blue|plant a|<timestamp>

當我從文件1中擦除文件2時,我想要包含的結果文件是

New File
------
acme|widg102|blue|plant b|<timestamp>
acme|widg002|yellow|plant a|<timestamp>

理想情況下,該解決方案使我可以指定兩個以上的文件,即從文件1中擦除文件2、3和4。

任何幫助將是巨大的!

由於您要求使用Bash,所以我決定只使用Bash。 完全沒有外部程序。

IFS='|'
declare -A scrub

while read f1 f2 rest; do
    scrub[$f2]=0
done < file2.txt

while read f1 f2 rest; do
    if [ ! ${scrub[$f2]} ]; then
        echo "$f1|$f2|$rest"
    fi
done < file1.txt

這會緩存要先清除的值,然后遍歷第一個文件中的候選值,打印未清除的值。 它不漂亮,但是是Bash。

這個awk可以將多個文件作為參數: (file1必須是最后一個)

 awk -F'|' 'ARGIND<ARGC-1{a[$2];next} !($2 in a)' fileN fileN-1..... file1

關鍵是awk的ARGC and ARGIND變量的用法。

用3個文件測試

kent$  head f*                                                  
==> f1 <==
acme|widg001|green|plant a|<timestamp>
acme|widg102|blue|plant b|<timestamp>
acme|widg002|yellow|plant a|<timestamp>

==> f2 <==
acme|widg001|blue|plant a|<timestamp>
acme|widg701|blue|plant a|<timestamp>

==> f3 <==
acme|widg102|blue|plant a|<timestamp>
acme|widg701|blue|plant a|<timestamp>

kent$  awk -F'|' 'ARGIND<ARGC-1{a[$2];next} !($2 in a)' f2 f3 f1
acme|widg002|yellow|plant a|<timestamp>

這看起來很近

join --check-order -v 1 -t\| -j 2 \
     <(sort -t \| -k2 file1) 
     <(sort -t \| -k2 file2)

它打印

widg002|acme|yellow|plant a|<timestamp
widg102|acme|blue|plant b|<timestamp>

除了以下事實外,這似乎是正確的

  • 由於join期望輸入的方式,該輸出在鍵列上排序
  • 鍵列移到最前面。 如果您有標題列,則--header將使此內容更加清晰。

如果您堅持手動排序列,請嘗試以下FORMAT規范:

-o "$(echo 1.{1..5})"

哪個打印

acme|widg002|yellow|plant a|<timestamp
acme|widg102|blue|plant b|<timestamp>

man joinman sort是您進行其他任何調整的朋友

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM