簡體   English   中英

如何從awk的輸入FILENAME變量中刪除路徑-基本名稱是否可用?

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

通過在第一行執行該部分,僅從每個文件中提取filenamef 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.

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