2017-05-12 64 views
1

假設一個文本文件(file1)包含多行字母字符串,每個字符串前面都有一個充當條形碼的短字母數字字符串。字母串的長度都是相同的,前面的字母數字不是。字母和字母數字字符串在每行中用空格分隔。通過bash工具從文本文件中提取列範圍

$ cat file1 
a1 abcdefghijklmnopqrstuvwxyz 
b27 abcdefghijklmnopqrstuvwxyz 
c4 abcdefghijklmnopqrstuvwxyz 

假設包含在列的範圍的信息的第二文件(file2)。該範圍總是小於字母字符串。

$ cat file2 
2-13 

我想開發中提取從file2字母串在file1指定的列範圍bash的代碼,同時保持條形碼。

$ sought_command file1 file2 
a1 bcdefghijklm 
b27 bcdefghijklm 
c4 bcdefghijklm 

我不清楚其中的bash電動工具會在這方面有所幫助,但推測awk將是可以做到這一點的工具。

注:我知道Python中的代碼可能是最容易寫的關於這個任務,我做了。但是,我發現我的Python實現過於緩慢,因爲要處理的字符串長度爲數萬個字符。因此,我刻意用bash工具來解決這個問題。

回答

3
$ awk 'NR==FNR{start=$1;lgth=$2;next} {print $1, substr($2,start,lgth)}' FS='-' file2 FS=' ' file1 
a1 bcdefghijklmn 
b27 bcdefghijklmn 
c4 bcdefghijklmn 

,或者如果第二字段是端部位置,而不是長度:

$ awk 'NR==FNR{start=$1;lgth=$2-$1+1;next} {print $1, substr($2,start,lgth)}' FS='-' file2 FS=' ' file1 
a1 bcdefghijklm 
b27 bcdefghijklm 
c4 bcdefghijklm 
+0

哇!對我來說,這是最好的力量。謝謝您的回答。 –

+1

不客氣,謝謝,但答案與bash無關。它是awk,它是一個完全獨立的工具,可以從任何UNIX shell(bash,ksh,csh,sh等)或Windows中調用。它恰好適用於所有UNIX安裝。使用bash或任何其他shell構造不適合您的問題 - 請參閱[https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-被認爲是壞習慣](https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice) –

+0

我剛剛意識到你的代碼就好像第二個'file2'是長度,而不是列範圍的停止位置。爲了糾正這個問題,我試圖修改你的命令爲'awk'NR == FNR {start = $ 1; lgth = $(expr $ 2- $ 1); next} {print $ 1,substr($ 2,start,lgth)} 'FS =' - 'file2 FS =''file1'。查看內部減法。但是,我的修改不起作用。你有什麼建議嗎? –

相關問題