2017-08-28 130 views
1

我有很多文件的第一行作爲標識符。隨後的行是標識符的產品。這裏是一個文件的例子:將第一行添加到文件開頭的每一行的shell

0G000001: 
Product_2221 
Product_2222 
Product_2122 
... 

我想把標識符放在文件的每一行的開始。最終的輸出將是這樣的:

0G000001: Product_2221 
0G000001: Product_2222 
0G000001: Product:2122 
.... 

我想爲所有的文件,我有一個循環。我一直在嘗試:

for i in $(echo `head -n1 file.$i.txt); 
    do 
cat - file.$i.txt > file_id.$i.txt; 
done 

但我只複製文件的第一行。我知道sed可以在文件的開頭添加特定文本,但我無法弄清楚它是否指定文本是文件的第一行,並且在循環上下文中。

+1

sed是爲's/old/new /'做的。你沒有做's/old/new /',所以你不應該考慮使用sed。對於其他任何事情,只需使用awk來實現更簡單,更清晰,更高效,更強大,更便攜,更具擴展性的解決方案。 –

回答

2

沒有顯式循環必要的:

awk ' 
    FNR==1 { close(out); out=FILENAME; sub(/\./,"_id&",out); hdr=$0; next } 
    { print hdr, $0 > out } 
' file.*.txt 
1

隨着awk

awk 'NR==1 { prod = $0 } NR>1 { print prod, $0 }' infile 

輸出:

0G000001: Product_2221 
0G000001: Product_2222 
0G000001: Product_2122 
+1

如果有多個文件,'FNR'會更好。 –

+0

@TomFenech:是的,但這需要更多代碼來處理結果。有關該解決方案,請參閱[Ed的回答](https://stackoverflow.com/a/45924191/1331399)。 – Thor

1

這可能爲你工作(GNU SED):

sed -ri '1h;1d;G;s/(.*)\n(.*)/\2 \1/' file ... 

保存在貨艙空間中的第一行(HS ),然後從模式空間(PS)中刪除它。對於每行(不是第一行),將HS附加到PS,然後交換行並用空格替換換行符。

1

一個sed命令,你想會是這樣的:

$ sed '1{h;d};G;s/\(.*\)\n\(.*\)/\2 \1/' infile 
0G000001: Product_2221 
0G000001: Product_2222 
0G000001: Product_2122 

這將執行以下操作:

1 {      # On the first line 
    h      # Copy the pattern space to the hold space 
    d      # Delete the line, move to next line 
} 
G       # Append the hold space to the pattern space 
s/\(.*\)\n\(.*\)/\2 \1/ # Swap the lines in the pattern space 

有些SEDS可能抱怨{h;d},需要一個額外的分號,{h;d;}

爲此就地一個文件,你可以使用

sed -i '1{h;d};G;s/\(.*\)\n\(.*\)/\2 \1/' infile 

爲GNU sed或

sed -i '' '1{h;d};G;s/\(.*\)\n\(.*\)/\2 \1/' infile 

的sed的Mac系統。或者,如果您的SED不支持-i都:

sed '1{h;d};G;s/\(.*\)\n\(.*\)/\2 \1/' infile > tmpfile && mv tmpfile infile 

做到在一個循環對所有目錄中的文件:

for f in /path/to/dir/*; do 
    sed -i '1{h;d};G;s/\(.*\)\n\(.*\)/\2 \1/' "$f" 
done 

,甚至直接與水珠:

sed -i '1{h;d};G;s/\(.*\)\n\(.*\)/\2 \1/' /path/to/dir/* 

後者確實與GNU sed一起工作;不確定其他seds。

1

的sed + 解決方案:

for f in *.txt; do sed -i '1d; s/^/'"$(head -n1 $f)"' /' "$f"; done 

  • -i - 修改文件就地

  • 1d; - 刪除一號線

  • $(head -n1 $f) - 提取文件的第一行(獲得標識符)

  • s/^/<identifier> / - 前置標識每一行的文件

相關問題