awk: 変更された列をファイルに追加し、元の列を保持します。

awk: 変更された列をファイルに追加し、元の列を保持します。

2つの列を持つファイルがあります。

path/path/target1.target2 column2

awkを使って印刷したいです。

column1 column2 target1 target2

修正するために次のように試しましたが、元の列が失われました。

$ awk '{gsub("\\..*","", $(gsub(".*/","", $1))); gsub(".*_","", $1); print $0}'
target1 column2

どうすればいいですか?この行動を説明できますか?

答え1

方法は次のとおりですawk

$ awk '{ 
         split($1,parts,"."); 
         sub(".*/","",parts[1]); 
         print $1, $2, parts[1], parts[2]
       }' file
path/path/target1.target2 column2 target1 target2

なぜあなたのものがうまくいかないのかエマ・ルーオが説明するこれは、値を変更しても$1期待どおりに印刷できないためです。

答え2

sed代わりに、以下を使用してくださいawk

sed -E 's!([^/]*)\.([^ ]*) (.*)!& \1 \2!'

単一行の例の出力:

path/path/target1.target2 column2 target1 target2

フィールドを独自のコマンドにawk置き換える理由については、gsub(参照man awk)文書に次のように記録されています。

gsub(r,s,t) gsub(r,s)グローバル置換、r変数内の正規表現に一致するすべての項目がt文字列s[...]で置き換えられます。

つまり、たとえばtwhere$1の値を指定した場合gsub(".*/","", $1)交換済み交換として。$1を適用する前に、別の変数にコピーする必要がありますgsub。それ以外の場合は、非標準を使用してgensub変更された文字列を返します。

答え3

awkを使用してください。

$ awk '{n=split($1,a,"[/.]"); print $0, a[n-1], a[n]}' file
path/path/target1.target2 column2 target1 target2

または必要に応じて:

$ awk '{x=$1; gsub(/.*\/|\./,OFS,x); print $0 x}' file
path/path/target1.target2 column2 target1 target2

元のスクリプトには、ここで説明しないでくださいいくつかの基本的な問題があります。 Arnold Robbinsが書いた「Effective AWKプログラミング、第5版」の本を入手して、それについて読んで、gsub()その$意味を読んでください。

答え4

使用幸せ(以前のPerl_6)

sed...今回の答えを得たので、PerlやRakuを使ってみてはいかがでしょうか?

~$ raku -ne 'my @a = .split(:skip-empty, /  \.  |  ^ .* <[/]> /)>>.words.flat; say @a.raku;'  file

#OR (more simply)

~$ -ne 'my @a = .split(:skip-empty, /  \.  |  ^ .* <[/]> /).words; say @a.raku;'   file

入力例:

path/path/target1.target2 column2

出力例:

path/path/target1.target2 column2 target1 target2

つまり、-ne非自動印刷コマンドラインフラグを使用して入力を1行ずつ読み込みます。split誰でも.または行の先頭から最後の行までのパステキストをスペースで区切られたパス(列など)で/除算します。wordsこれは@a配列に保存されます。出力の場合、最初の行は$_そのまま印刷され、その後に配列の最初の2つの@a要素が印刷されます。

https://raku.org

関連情報