我有兩個串列list1,list2每行都有一個檔案名。我想要一個result只有 inlist2而不是 in的所有檔案名list1,而不考慮特定的檔案擴展名(但不是全部)。使用 Linux bash,任何不需要任何額外安裝的命令。在示例串列中,我確實知道我希望忽略的所有檔案擴展名。我做了嘗試,但它根本不起作用,我不知道如何解決它。為我的缺乏經驗道歉。
我希望忽略以下擴展名: .x .xy .yx .y .jpg
list1.txt
text.x
example.xy
file.yx
data.y
edit
edit.jpg
list2.txt
text
rainbow.z
file
data.y
sunshine
edit.test.jpg
edit.random
結果.txt
rainbow.z
sunshine
edit.test.jpg
edit.random
我的嘗試:
while read LINE
do
line2=$LINE
sed -i 's/\.x$//g' $LINE $line2
sed -i 's/\.xy$//g' $LINE $line2
sed -i 's/\.yx$//g' $LINE $line2
sed -i 's/\.y$//g' $LINE $line2
then sed -i -e '$line' result.txt;
fi
done < list2.txt
編輯:我忘記了兩個要求。檔案名可以有 . 在它們中,并非所有檔案名都必須具有擴展名。我知道必須忽略的擴展名。我相應地修改了清單。
uj5u.com熱心網友回復:
對于awk此任務,解決方案可能更有效:
awk '
{ f=$0; sub(/\.(xy?|yx?|jpg)$/,"",f) }
NR==FNR { a[f]; next }
!(f in a)
' list1.txt list2.txt > result.txt
uj5u.com熱心網友回復:
comm可以做到這一點。
您可以預處理輸入:
- 剝去足夠的東西
- 排序(
comm期望排序輸入) - 洗掉重復項
ss()( sed 's/\.\(x\|xy\|yx\|y\|jpg\)$//' "$@" | sort -u )
comm -13 <(ss list1.txt) <(ss list2.txt) >result.txt
你的代碼是:
while read LINE
do
line2=$LINE
sed -i 's/\.x$//g' $LINE $line2
sed -i 's/\.xy$//g' $LINE $line2
sed -i 's/\.yx$//g' $LINE $line2
sed -i 's/\.y$//g' $LINE $line2
then sed -i -e '$line' result.txt;
fi
done < list2.txt
一些立即跳出來的問題:
- 語法錯誤 -
then/fi但沒有匹配if - 你永遠不會訪問
list1 - 使用變數時不要參考變數,因此空格和特殊字符會導致問題
while read ... sed ... sed ... sed ...效率低下 - sed 的多次呼叫而不是一次,并且 sed 的回圈將隱式執行sed期望檔案引數不是字串sed -i將嘗試覆寫輸入檔案引數- 您將
result.txt其用作 sed 的輸入和輸出,但從不為其分配任何內容 - 您嘗試使用 data (
$line) 作為 sed 命令,而不是將 sed 命令應用于該資料 - 因為您使用了單引號,所以
sed -i -e '$line'將嘗試在line輸入的最后一行 ($)上運行(不存在的)sed 命令 gs///錨定搜索時不執行任何操作的選項
uj5u.com熱心網友回復:
我會使用join:
$ join -t. -j1 -v2 -o 2.1,2.2 <(sort list1.txt) <(sort list2.txt) | sed 's/\.$//'
rainbow.z
sunshine
(sed需要變成sunshine.的位sunshine)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/527931.html
標籤:linux重击脚本
