AWK:打印列变量,每个字符由 space 分隔
AWK: print column variable with each character separated by a space
我有一个非常大的文件,如下所示:
ID Class Values
126 1 332222330442022...
753 1 332222330442022...
119 1 402224220402022...
830 1 002233440232022...
944 1 222222220002022...
第 3 列是一个包含 50,000 个字符的字符串。我需要忽略顶行,删除第 2 列,将第 3 列中的所有 3 或 4 替换为 1,最后打印第 3 列,每个字符由 space.
分隔
所以期望的输出是:
126 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2...
753 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2...
119 1 0 2 2 2 1 2 2 0 1 0 2 0 2 2...
830 0 0 2 2 1 1 1 1 0 2 1 2 0 2 2...
944 2 2 2 2 2 2 2 2 0 0 0 2 0 2 2...
由于文件太大,如果可能,最好避免在第 3 列使用拆分。
到目前为止,除了打印由 space 分隔的第 3 列外,我可以实现所有内容:
awk -F " " 'NR!= 1 { gsub(3,1,); gsub(4,1,); printf "%s\t%s\n", , }' ./input.txt
我知道我可以使用类似于此处答案的 split() (),但我还需要打印 $1。是否可以在同一个 awk 命令中分隔第 3 列?
你可以使用这个awk
:
awk -v OFS='\t' 'NR > 1 {
gsub(/[34]/, 1, )
gsub(/./, "& ", )
sub(/ $/, "", )
print ,
}' file
126 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2
753 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2
119 1 0 2 2 2 1 2 2 0 1 0 2 0 2 2
830 0 0 2 2 1 1 1 1 0 2 1 2 0 2 2
944 2 2 2 2 2 2 2 2 0 0 0 2 0 2 2
使用您显示的示例,请尝试以下 awk
代码。在 GNU awk
.
中编写和测试
awk '
BEGIN{
FS=OFS="\t"
}
FNR>1{
val=""
gsub(/[34]/, 1, )
num=split(,arr,"")
for(i=1;i<=num;i++){
val=(val?val OFS:"") arr[i]
}
print ,val
}
' Input_file
说明:为以上代码添加详细说明。
awk ' ##Starting awk program from here.
BEGIN{ ##Starting BEGIN section of awk program from here.
FS=OFS="\t" ##Setting FS and OFS as tab here.
}
FNR>1{ ##If line is not first line then do following.
val="" ##Nullifying val here.
gsub(/[34]/, 1, ) ##Globally substituting 3 4 to 1 in here.
num=split(,arr,"") ##Splitting into array arr with NULL delimiter.
for(i=1;i<=num;i++){ ##Running for loop from 1 to till value of num.
val=(val?val OFS:"") arr[i] ##Creating val which has all elements of arr added with spaces.
}
print ,val ##Printing and val here.
}
' Input_file ##Mentioning Input_file name here.
我有一个非常大的文件,如下所示:
ID Class Values
126 1 332222330442022...
753 1 332222330442022...
119 1 402224220402022...
830 1 002233440232022...
944 1 222222220002022...
第 3 列是一个包含 50,000 个字符的字符串。我需要忽略顶行,删除第 2 列,将第 3 列中的所有 3 或 4 替换为 1,最后打印第 3 列,每个字符由 space.
分隔所以期望的输出是:
126 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2...
753 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2...
119 1 0 2 2 2 1 2 2 0 1 0 2 0 2 2...
830 0 0 2 2 1 1 1 1 0 2 1 2 0 2 2...
944 2 2 2 2 2 2 2 2 0 0 0 2 0 2 2...
由于文件太大,如果可能,最好避免在第 3 列使用拆分。
到目前为止,除了打印由 space 分隔的第 3 列外,我可以实现所有内容:
awk -F " " 'NR!= 1 { gsub(3,1,); gsub(4,1,); printf "%s\t%s\n", , }' ./input.txt
我知道我可以使用类似于此处答案的 split() (
你可以使用这个awk
:
awk -v OFS='\t' 'NR > 1 {
gsub(/[34]/, 1, )
gsub(/./, "& ", )
sub(/ $/, "", )
print ,
}' file
126 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2
753 1 1 2 2 2 2 1 1 0 1 1 2 0 2 2
119 1 0 2 2 2 1 2 2 0 1 0 2 0 2 2
830 0 0 2 2 1 1 1 1 0 2 1 2 0 2 2
944 2 2 2 2 2 2 2 2 0 0 0 2 0 2 2
使用您显示的示例,请尝试以下 awk
代码。在 GNU awk
.
awk '
BEGIN{
FS=OFS="\t"
}
FNR>1{
val=""
gsub(/[34]/, 1, )
num=split(,arr,"")
for(i=1;i<=num;i++){
val=(val?val OFS:"") arr[i]
}
print ,val
}
' Input_file
说明:为以上代码添加详细说明。
awk ' ##Starting awk program from here.
BEGIN{ ##Starting BEGIN section of awk program from here.
FS=OFS="\t" ##Setting FS and OFS as tab here.
}
FNR>1{ ##If line is not first line then do following.
val="" ##Nullifying val here.
gsub(/[34]/, 1, ) ##Globally substituting 3 4 to 1 in here.
num=split(,arr,"") ##Splitting into array arr with NULL delimiter.
for(i=1;i<=num;i++){ ##Running for loop from 1 to till value of num.
val=(val?val OFS:"") arr[i] ##Creating val which has all elements of arr added with spaces.
}
print ,val ##Printing and val here.
}
' Input_file ##Mentioning Input_file name here.