從控制檔案中讀取數字並從資料檔案中提取匹配的行號

從控制檔案中讀取數字並從資料檔案中提取匹配的行號

我有一個控製檔 - cntl.txt

2
3
5

資料檔-data.txt

red
blue
yellow
green
violet
orange

我需要讀取控制檔中匹配的行,這裡預期的輸出是:

blue
yellow 
violet

答案1

一個非常低效的解決方案的範例:

for i in $(<control.txt); do awk -v c=$i 'NR~c{ print $0 }' data.txt; done;

我還報告了我今晚學到的一個很好的解決方案:

awk 'FNR==NR{ z[$0]++;next }; FNR in z' control.txt data.txt

答案2

僅使用POSIX 指定Sed 的特點:

sed -n -e "$(sed '/./s/$/p/' cntl.txt)" data.txt

當然,如果您的cntl.txt文件除了數字之外還有行,您可能會收到錯誤。但如果它有空行,這些將被正確處理(即它們不會影響輸出)。

答案3

嘗試這個:

join <(nl data.txt|sort -k1b,1) <(cat cntl.txt|sort -k1b,1) | sort -nk1,1 | cut -d' ' -f2-

nl - 將為您舉行

 1  red
 2  blue
 3  yellow
 4  green
 5  violet
 6  orange

| sort -k1b,1 - 將按行號(第一個欄位)按字典順序對它們進行排序

貓 cntl.txt| sort -k1b,1 - 將以相同的順序對控制檔進行排序

2
3
5

join <() <() - 將在第一個欄位(即行號)上將排序(和編號)的「資料」與排序的「控制」連接起來

2 blue
3 yellow
5 violet

|sort -nk1,1 - 將以數字方式重新排序結果(將行重新按順序排列)

| cut -d' ' -f2- - 將刪除行號字段

blue
yellow
violet

答案4

另一個可能的解決方案:

IFS=$'\n' read -d '' -r -a colors < 'data.txt'; unset IFS;

for i in $(<cntl.txt); do
        echo ${colors[i-1]} 
done

IFS 行將內部檔案分隔符設定為換行符,並將 data.txt 中的每一行插入陣列中。之後,循環遍歷 cntl.txt 中的行並列印其中具有給定索引的陣列元素(負 1,因為您從 1 開始 data.txt,而不是從 0 開始,否則就沒有必要)。

相關內容