2012-11-22 64 views
0

我有兩個文件。其中含有動物名稱:在兩個不同的文件中映射兩個字符串,這兩個文件在bash中的開始行中共享相同的數字

[email protected]:~$ cat animals.txt 
98 white elefant 
103 brown dog 
111 yellow cat 
138 blue whale 
987 pink pig 
[email protected]:~$ 

..和其他包含在他們居住的地方:前

[email protected]:~$ cat places.txt 
98 safari 
99 
103 home 
105 
109 
111 flat 
138 ocean 
500 
987 farm 
989 
[email protected]:~$ 

許多動物名稱animals.txt指向正確的位置。輸出應該是這樣的:

[email protected]:~$ ./animals.sh 
safari white elefant 
home brown dog 
flat yellow cat 
ocean blue whale 
farm pink pig 
[email protected]:~$ 

什麼是在bash映射動物名稱與位置最優雅的解決方案是什麼?

我做了這樣的:

#!/usr/bin/env bash 

#content of animals.txt file is stored into "$animals" variable using command substitution 
animals=$(<animals.txt) 

#content of places.txt file is stored into "$places" variable using command substitution 
places=$(<places.txt) 


#read(bash builtin) reads "$animals" variable line by line 
while read line; do 

    #"$animals_number" variable contains number in the beginning of the line; for example "98" in case of first line 
    animals_number=$(echo "$line" | sed 's/ .*$//') 
    #"$animals_name" variable contains string after number; for example "white elefant" in case of first line 
    animals_name=$(echo "$line" | sed 's/[0-9]* //') 
    #"$animals_place" variable contains the string after line which starts with "$animals_number" integer in places.txt file; 
    #for example "safari" in case of first line 
    animals_place=$(echo "$places" | grep -Ew "^$animals_number" | sed 's/.* //') 
    #printf is used to map two strings which share the same integer in the beginning of the line 
    printf '%s\t%s\n' "$animals_place" "$animals_name" 

#process substitution is used to redirect content of "$animals" variable into sdtin of while loop 
done < <(echo "$animals") 

不過,我不知道這是解決這個問題的最優雅/有效的方式。任何其他方法/技巧?

回答

3
while read id place; do places[$id]=$place;       done < places.txt 
while read id animal; do printf '%s\t%s\n' "${places[$id]}" "$animal"; done < animals.txt 
+0

優秀的使用read'的' –

0
join <(sort animals.txt) <(sort places.txt) | sort -n 

不幸的是,join沒有一個 「數字排序」 選項,據我所知;否則你可能只是join這兩個文件,而不是將所有內容整理兩次。 (如果將前導零置入文件中,它將在沒有sort的情況下工作。)

最近的ubuntus和其他Linux發行版可能會將LANG設置爲假定的語言環境。這對sort是致命的,這是區域意識,不像join;對於上述工作,joinsort必須同意分揀順序。如果你得到這樣的錯誤:

join: /dev/fd/63:5: is not sorted: 98 white elefant 

那就試試這個:

(export LC_ALL=C; join <(sort animals.txt) <(sort places.txt) | sort -n) 
相關問題