我有一个* .csv文件。价值如下
"ASDP02","8801942183589"
"ASDP06","8801939151023"
"CSDP04","8801963981740"
"ASDP09","8801946305047"
"ASDP12","8801941195677"
"ASDP05","8801922826186"
"CSDP08","8801983008938"
"ASDP04","8801944346555"
"CSDP11","8801910831518"
或有时值如下
"8801989353984","KSDP05"
"8801957608165","ASDP11"
"8801991455848","CSDP10"
"8801981363116","CSDP07"
"8801921247870","KSDP07"
"8801965386240","CSDP06"
"8801956293036","KSDP10"
"8801984383904","KSDP11"
"8801944211742","ASDP09"
我只想把数值(例如8801989353984)放在第一列。是否可以使用BASH脚本?
答案 0 :(得分:1)
Sed
也是你的朋友
<强>输入强>
cat 41189347
"ASDP02","8801942183589"
"ASDP06","8801939151023"
"CSDP04","8801963981740"
"ASDP09","8801946305047"
"ASDP12","8801941195677"
"ASDP05","8801922826186"
"CSDP08","8801983008938"
"ASDP04","8801944346555"
"CSDP11","8801910831518"
<强>脚本强>
sed -E 's/^("[[:alpha:]]+.*"),("[[:digit:]]+")$/\2,\1/' 41189347
<强>输出强>
"8801942183589","ASDP02"
"8801939151023","ASDP06"
"8801963981740","CSDP04"
"8801946305047","ASDP09"
"8801941195677","ASDP12"
"8801922826186","ASDP05"
"8801983008938","CSDP08"
"8801944346555","ASDP04"
"8801910831518","CSDP11"
答案 1 :(得分:1)
awk
救援!
$ awk -F, -v OFS=, '$1~/[A-Z]/{t=$2;$2=$1;$1=t}1' file
如果第一个字段有alpha字符,则交换第一列和第二列并打印。
答案 2 :(得分:0)
Bash可以完成工作,但awk可能是重新安排文件的更好选择:
sample.csv:
"ASDP02","8801942183589"
"8801944211742","ASDP09"
命令:
awk -F, 'BEGIN{OFS=","}{$1=$1;if(substr($1, 2, length($1) - 2) + 0 == substr($1, 2, length($1) - 2)){print $1,$2}else{print $2,$1}}' sample.csv
substr($1, 2, length($1) - 2) + 0 == substr($1, 2, length($1) - 2)
检查列是否为数字。如果是,则打印原始行,否则切换column1和column2 输出:
"8801942183589","ASDP02"
"8801944211742","ASDP09"
答案 3 :(得分:0)
以下命令假定CSV文件中的单元格不包含换行符和逗号。否则,您应该使用Perl,PHP或其他能够正确解析CSV文件的编程语言编写更复杂的脚本。但是Bash肯定不适合这项任务。
<强>的Perl 强>
perl -F, -nle '@F = reverse @F if $F[0] =~ /^"\d+"$/;
print join(",", @F)' file
小心,如果单元格包含换行符或逗号,请使用Perl的Text::CSV
模块。虽然在Perl中这是一项简单的任务,但它超出了当前问题的范围。
该命令用逗号(-F,
)分割输入行,并将结果存储到每行的@F
数组中。如果第一个字段$F[0]
与正则表达式匹配,则数组中的项目将反转。您也可以这样交换项目:($F[0], $F[1]) = ($F[1], $F[0])
。
最后,用逗号连接数组项,并将打印到标准输出。
如果您要就地修改文件,请使用-i
选项:perl -i.backup -F, ...
。
<强> AWK 强>
awk -F, -vOFS=, '/^"[0-9]+",/ {print; next}
{ t = $1; $1 = $2; $2 = t; print }' file
输入和输出字段分隔符设置为,
-F,
和-vOFS=,
。
如果该行符合模式/^"[0-9]+",/
(该行以&#34;数字&#34; CSV列开头),脚本将打印记录并前进到next
记录。否则执行下一个块。
在下一个块中,它交换前两列并将结果打印到标准输出。
如果您想就地编辑文件,请参阅this question的答案。
答案 4 :(得分:0)
您可以创建纯bash脚本来生成具有所需结构的其他文件:
#!/bin/bash
csv_file="/path/to/your/csvfile"
output_file="/path/to/output_file"
#Optional
rm -rf "${output_file}"
readarray -t LINES < <(cat < "${csv_file}" 2> /dev/null)
for item in "${LINES[@]}"; do
if [[ $item =~ ^\"([0-9A-Z]+)\"\,\"([0-9]+)\" ]]; then
echo "\"${BASH_REMATCH[2]}\",\"${BASH_REMATCH[1]}\"" >> "${output_file}"
else
echo "$item" >> "${output_file}"
fi
done
即使您的文件是“混合”,这也有效。我的意思是某些行格式正确,其他行格式不正确。