[英]How to pipe a file back into a loop in bash?
我試圖找到一種從文件中刪除一對線的方法,該對中的第一行包含一個唯一的ID,第二行包含一個字符串。 我在想一些類似的事情
for i in $(cat idlist.txt ); do grep -v -A1 $i file1
但是我不確定如何在每次迭代時將循環的輸出返回管道? 有小費嗎?
我要更改的文件基本上采用以下格式
uniqueID.1
OJNEFONEOIWENWEJNEWEJ
uniqueID.2
HHTHANJAHTNTHAJNTEOEJ
我想要一些ID +字符串。
謝謝
在這種情況下, awk
可能是一個不錯的選擇。 這是基本概念的快速版本,包含在bash
腳本中:
#!/bin/bash
awk '
FNR == 1 { filenum++ }
filenum == 1 { ids[$0] = 1 }
filenum == 2 {
if ((FNR % 2) == 1) { id = $0 }
else if (ids[id] != 1) { print id; print }
}
' idlist.txt file.txt
這個想法是通過添加要忽略的標簽到關聯數組ids
來處理idlist文件,然后成對處理第二個文件,注意第一行的id,然后打印該文件,如果id不是,則打印下一行ids
。
如果您需要“就地”修改文件,則可以使用與建議的相同的mv
東西在這里工作。
成績單:
$ cat idlist.txt
id.2
id.4
id.6
$ cat file.txt
id.1
stuff 1
id.2
stuff 2
id.3
stuff 3
id.4
stuff 4
id.5
stuff 5
id.6
stuff 6
id.7
stuff 7
$ ./skipper.sh
id.1
stuff 1
id.3
stuff 3
id.5
stuff 5
id.7
stuff 7
讀取和寫入列表中每個模式的文件似乎效率很低。 最好只讀取和處理一次文件,一次性刪除所有ID。
如何執行此操作取決於該文件idlist.txt
什么樣的ID。 從將模式傳遞給grep
的方式來看,它們似乎必須是單詞或簡單的正則表達式,因此您可以嘗試以下方法。
首先,將ID轉換為sed
程序:
PROGRAM=$(while read ID; do echo "/$ID/{N;d;}"; done < idlist.txt)
然后使用sed
運行程序並就地更新文件:
sed -i '' -e "$PROGRAM" -- file1
程序的工作方式是/$ID/
匹配包含id的行,然后N
命令從文件中讀取下一行,而d
命令刪除這兩行。 其他行正常打印。 (顯然,這取決於$ID
是不包含/
字符的有效基本正則表達式。)
如果您的sed
版本接受“擴展的正則表達式”(程序的GNU版本的-r
選項或BSD版本的-E
選項),則可以將所有ID編譯為一個正則表達式:
PROGRAM=$(printf '/('; tr '\n' '|' < idlist.txt; printf '.^)/{N;d;}')
sed -r -i '' -e "$PROGRAM" -- file1
(這里的.^
是可能不匹配的正則表達式;它在正則表達式中的final |
之后,以確保交替中的final子句不存在匹配項。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.