![使用 miller 将小写字母转换为大写字母并将输出输出到新列](https://linux22.com/image/224589/%E4%BD%BF%E7%94%A8%20miller%20%E5%B0%86%E5%B0%8F%E5%86%99%E5%AD%97%E6%AF%8D%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%A4%A7%E5%86%99%E5%AD%97%E6%AF%8D%E5%B9%B6%E5%B0%86%E8%BE%93%E5%87%BA%E8%BE%93%E5%87%BA%E5%88%B0%E6%96%B0%E5%88%97.png)
我想将列复制NAME
到列NAME-LOWERCASE
。NAME-LOWERCASE
应该只包含小写字母。除此以外,所有列中的大写字母均应保持不变NAME-LOWERCASE
输入
NAME,test
PTC,N
Agri,Y
E-example,N
ForYou,N
Willy Nes,Y
输出
NAME,NAME-LOWERCASE,test
PTC,ptc,N
Agri,agri,Y
E-example,E-example,N
ForYou,foryou,N
Willy Nes,willy nes,Y
我知道如何从另一列创建新列并重新排序
mlr -I --csv \
put '$FIRSTNAME = sub($FULLNAME," .*","")' then \
reorder -f FULLNAME,LASTNAME,EMAIL,DOMAIN,COMPANY input.csv
我知道如何将大写转换为小写
mlr --csv -N case -l
如何组合这两个命令?或者还有另一个米勒命令来实现我的目标?
答案1
如果你跑
mlr --csv put '${NAME-LOWERCASE}=tolower($NAME)' then \
reorder -f NAME,NAME-LOWERCASE,test input.csv
你会得到NAME-LOWERCASE
小写的。
NAME,NAME-LOWERCASE,test
PTC,ptc,N
Agri,agri,Y
E-example,e-example,N
ForYou,foryou,N
Willy Nes,willy nes,Y
它是tolower
功能。
答案2
如果您的数据确实像您显示的那样简单,,
字段内没有换行符,您可以执行以下操作:
$ awk -F, -v OFS="," '{ $3=$2; } (NR==1) ? $2="NAME-LOWERCASE" : $2=tolower($1)' file
NAME,NAME-LOWERCASE,test
PTC,ptc,N
Agri,agri,Y
E-example,e-example,N
ForYou,foryou,N
Willy Nes,willy nes,Y
在这里,我们将输入字段分隔符设置为逗号 ( -F,
),然后将特殊变量OFS
(输出字段分隔符)设置为逗号 ( -v OFS=,
)。然后,对于每一行,我们添加一个新的第三个字段,其值与当前第二个字段 ( $3=$2
) 相同。然后我们使用三元运算符检查这是否是第一行 ( NR==1
),如果是,我们将第二个字段设置为字符串 ( $2="NAME-LOWERCASE"
),如果不是,我们将第二个字段设置为第一个字段的小写版本 ( $2=tolower($1)
)。在 中awk
,当表达式计算为 true 时的默认操作是打印该行,并且由于该表达式将始终计算为 true (因为它始终要么是第一行,要么不是第一行),这会导致打印每个修改的行。
或者,假设您的数据如您所显示的那样简单,您可以使用 perl:
$ perl -F, -lane '$,=","; $. == 1 ? print $F[0],"NAME-LOWERCASE",$F[1] : print $F[0],lc($F[0]), $F[1]' file
NAME,NAME-LOWERCASE,test
PTC,ptc,N
Agri,agri,Y
E-example,e-example,N
ForYou,foryou,N
Willy Nes,willy nes,Y
使-a
perl 的行为类似于 awk,根据 给出的字符分割每个输入行-F
。意思-n
是“逐行读取输入文件并-e
在每行上运行给出的脚本”。-l
从输入中删除尾随换行符,并向每个调用添加尾随换行符print
。对于-a
,字段被分割成特殊数组@F
,因此第一个字段是$F[0]
,秒$F[1]
等等。最后,特殊变量$,
是输出字段分隔符,这里我们将其设置为 a,
以打印逗号分隔的输出。
脚本本身非常简单:它首先设置$,
为,
,然后如果这是第一行($.
保存当前行号),它会打印第一个字段,然后是字符串"NAME-LOWERCASE"
,然后是第二个字段,对于所有其他行,它会打印第一个字段,然后是小写 ( lc($F[0])
) 的第一个字段,然后是第二个字段。
你可以写同样的东西:
perl -F, -lane '
if($. == 1){
print $F[0],"NAME-LOWERCASE",$F[1];
}
else{
print $F[0],lc($F[0]), $F[1];
}' file
答案3
使用awk
:
$ awk 'BEGIN{FS=OFS=","}
{$1 = $1 OFS ((NR==1) ? "NAME-LOWERCASE" : tolower($1)) }1'file
使用csvsql
:
$ csvsql -I --query 'SELECT NAME,lower(NAME) AS "NAME-LOWERCASE",test FROM file' file.csv