Linux 剪切、粘贴
Linux cut, paste
我必须编写一个脚本文件来剪切以下列并将其粘贴到新的 .arff 文件中同一行的末尾。我想文件类型无关紧要。
当前文件:
63,male,typ_angina,145,233,t,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50'
67,male,asympt,160,286,f,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1'
输出应该是:
male,typ_angina,145,233,t,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50',63
male,asympt,160,286,f,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1',67
我该怎么做?使用 Linux 脚本文件?
更短的 awk 解决方案:
$ awk -F, '{$(NF+1)=;sub(",","")}1' OFS=, input.txt
给出:
male,typ_angina,145,233,t,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50',63
male,asympt,160,286,f,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1',67
解释:
{$(NF+1)= # add extra field with value of field
sub(",","") # search for string "," in [=12=], replace it with ""
}1 # print [=12=]
编辑:阅读您提出问题后的评论,看起来您交换的列比第一行到行尾的列更多。您可以考虑使用多次调用的交换函数:
func swap(i,j){s=$i; $i=$j; $j=s}
但是,当您想将一列移到行尾时,这将不起作用。因此,让我们更改该功能:
func swap(i,j){
s=$i
if (j>NF){
for (k=i;k<NF;k++) $k=$(k+1)
$NF=s
} else {
$i=$j
$j=s
}
}
现在您可以这样做了:
$ cat tst.awk
BEGIN{FS=OFS=","}
{swap(1,NF+1); swap(2,5)}1
func swap(i,j){
s=$i
if (j>NF){
for (k=i;k<NF;k++) $k=$(k+1)
$NF=s
} else {
$i=$j
$j=s
}
}
和:
$ awk -f tst.awk input.txt
male,t,145,233,typ_angina,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50',63
male,f,160,286,asympt,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1',67
sed -r 's/^([^,]*),(.*)$/,/' Input_file
简要说明,
^([^,]*)
匹配第一个字段,逗号分隔,后面的</code>指的是匹配</li>
<li><code>(.*)$
将是除第一个逗号之外的剩余部分,而
将引用匹配
为什么要用sed或者awk,shell可以轻松搞定
while read l;do echo ${l#*,},${l%%,*};done <infile
如果是带\r的win文件
while read l;do f=${l%[[:cntrl:]]};echo ${f#*,},${l%%,*};done <infile
如果你想保留文件。
printf "%s" "$(while read l;do f=${l%[[:cntrl:]]};printf "%s\n" "${f#*,},${l%%,*}";done <infile)">infile
我必须编写一个脚本文件来剪切以下列并将其粘贴到新的 .arff 文件中同一行的末尾。我想文件类型无关紧要。
当前文件:
63,male,typ_angina,145,233,t,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50'
67,male,asympt,160,286,f,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1'
输出应该是:
male,typ_angina,145,233,t,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50',63
male,asympt,160,286,f,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1',67
我该怎么做?使用 Linux 脚本文件?
更短的 awk 解决方案:
$ awk -F, '{$(NF+1)=;sub(",","")}1' OFS=, input.txt
给出:
male,typ_angina,145,233,t,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50',63
male,asympt,160,286,f,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1',67
解释:
{$(NF+1)= # add extra field with value of field
sub(",","") # search for string "," in [=12=], replace it with ""
}1 # print [=12=]
编辑:阅读您提出问题后的评论,看起来您交换的列比第一行到行尾的列更多。您可以考虑使用多次调用的交换函数:
func swap(i,j){s=$i; $i=$j; $j=s}
但是,当您想将一列移到行尾时,这将不起作用。因此,让我们更改该功能:
func swap(i,j){
s=$i
if (j>NF){
for (k=i;k<NF;k++) $k=$(k+1)
$NF=s
} else {
$i=$j
$j=s
}
}
现在您可以这样做了:
$ cat tst.awk
BEGIN{FS=OFS=","}
{swap(1,NF+1); swap(2,5)}1
func swap(i,j){
s=$i
if (j>NF){
for (k=i;k<NF;k++) $k=$(k+1)
$NF=s
} else {
$i=$j
$j=s
}
}
和:
$ awk -f tst.awk input.txt
male,t,145,233,typ_angina,left_vent_hyper,150,no,2.3,down,0,fixed_defect,'<50',63
male,f,160,286,asympt,left_vent_hyper,108,yes,1.5,flat,3,normal,'>50_1',67
sed -r 's/^([^,]*),(.*)$/,/' Input_file
简要说明,
^([^,]*)
匹配第一个字段,逗号分隔,后面的</code>指的是匹配</li> <li><code>(.*)$
将是除第一个逗号之外的剩余部分,而将引用匹配
为什么要用sed或者awk,shell可以轻松搞定
while read l;do echo ${l#*,},${l%%,*};done <infile
如果是带\r的win文件
while read l;do f=${l%[[:cntrl:]]};echo ${f#*,},${l%%,*};done <infile
如果你想保留文件。
printf "%s" "$(while read l;do f=${l%[[:cntrl:]]};printf "%s\n" "${f#*,},${l%%,*}";done <infile)">infile