簡體   English   中英

如何將文件通過管道傳送回bash中的循環?

[英]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.

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