[英]How to remove the path from awk's input FILENAME variable - is basename available somehow?
以下命令
gawk '{print $0, FILENAME}' input.txt > result.txt
其中input.txt是:
FIXED3 LENGTH7 FILE FORMAT 00001
FIXED2 LENGTH8 FILE FORMAT 00002
FIXED2 LENGTH20 FILE FORMAT 00003
FIXED1 LENGTH20 FILE FORMAT 00004
產生以下所需結果:
FIXED3 LENGTH7 FILE FORMAT 00001 input.txt
FIXED2 LENGTH8 FILE FORMAT 00002 input.txt
FIXED2 LENGTH20 FILE FORMAT 00003 input.txt
FIXED1 LENGTH20 FILE FORMAT 00004 input.txt
但是,如果使用如下所示的文件路徑:
gawk '{print $0, FILENAME}' /cygdrive/c/dev/data/input.txt > result.txt
然后,附加到每行的FILENAME也包含路徑。 這是我要糾正的,我希望得到與上述第一種情況相同的結果。
FIXED3 LENGTH7 FILE FORMAT 00001 /cygdrive/c/dev/data/input.txt
FIXED2 LENGTH8 FILE FORMAT 00002 /cygdrive/c/dev/data/input.txt
FIXED2 LENGTH20 FILE FORMAT 00003 /cygdrive/c/dev/data/input.txt
FIXED1 LENGTH20 FILE FORMAT 00004 /cygdrive/c/dev/data/input.txt
這是一種方法:
$ gawk '{f=FILENAME; sub(/^.*\//,"",f); print $0, f}' ../here/file
FIXED3 LENGTH7 FILE FORMAT 00001 file
FIXED2 LENGTH8 FILE FORMAT 00002 file
FIXED2 LENGTH20 FILE FORMAT 00003 file
FIXED1 LENGTH20 FILE FORMAT 00004 file
解釋:
$ gawk '{
f=FILENAME # copy the filename to f
sub(/^.*\//,"",f) # process f instead, removeall from beginning to last /
print $0, f # etc. etc.
}' ../here/file
或者因為您提到過gawk
:
$ gawk '{print $0, gensub(/^.*\//,"",1,FILENAME)}' ../here/file
用/
將FILENAME
分割成一個數組,並輸出數組的最后一個元素:
awk '{n=split(FILENAME,array,"/"); print $0, array[n]}' /cygdrive/c/dev/data/input.txt
為提高效率和簡潔性進行了一些調整:
gawk 'FNR==1{f=gensub(".*/","",1,FILENAME)} $(NF+1)=f'
通過在第一行執行該部分,僅從每個文件中提取filename
( f
here)一次。
並且由於FILENAME
不會為空,因此只需將其附加到該行中,即可隱含{print $0}
。
但是,如果不是單個空格,則會更改輸出分隔符。
如果不是您想要的,請使用下面的一種:
gawk 'FNR==1{f=gensub(".*/","",1,FILENAME)}{print $0 OFS f}'
您可以嘗試以下嗎? 它只會在第一行運行以獲取確切的Input_file名稱,而不會在文件的每一行運行。
awk 'FNR==1{if(FILENAME~/\//){sub(/.*\//,"",FILENAME)}} {print $0,FILENAME}' Input_file
這種方法的可能好處:
1-不在每一行上生成編輯的文件名,獲取本身在第一行上,而在所有其他行中僅打印prinintg。
2-沒有創建數組/內存占位符,因此在大型文件上也應該是FAST。
3-因為我只是打印它,而不用它的文件名值創建任何附加列,這也可以節省運行此代碼的時間。
編輯:也有另外一個想法,您可以簡單地導航到存在Input_file的新目錄,並可以返回代碼/一個內襯本身,例如以下示例。 恕我直言,我希望這將是這里提到的所有其他解決方案中最快的一個(因為我們在這里沒有進行任何數據操作,而且我們也使用了您以前使用過的相同命令:))
cd /cygdrive/c/dev/data/ && awk '{print $0,FILENAME}' input.txt && cd -
該命令的特殊之處在於它將返回到您正在運行代碼的原始目錄,因此您永遠不會感覺到您導航到任何地方:)
另一個awk
使用/
作為分隔符
gawk -F"/" ' { printf("%s ",$0) ; $0=FILENAME } { print $NF } ' /home/full/path/input.txt
用您給定的輸入
$ cat /cygdrive/c/dev/data/input.txt
FIXED3 LENGTH7 FILE FORMAT 00001
FIXED2 LENGTH8 FILE FORMAT 00002
FIXED2 LENGTH20 FILE FORMAT 00003
FIXED1 LENGTH20 FILE FORMAT 00004
$ gawk -F"/" ' { printf("%s ",$0) ; $0=FILENAME } { print $NF } ' /cygdrive/c/dev/data/input.txt
FIXED3 LENGTH7 FILE FORMAT 00001 input.txt
FIXED2 LENGTH8 FILE FORMAT 00002 input.txt
FIXED2 LENGTH20 FILE FORMAT 00003 input.txt
FIXED1 LENGTH20 FILE FORMAT 00004 input.txt
$
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.