我遇到客户需要复制CSV文件中的列的问题。这些值总是相同的,不幸的是我们的API不允许在JSON中指定重复的列。
例如,我有以下列结构和值:
Name, Surname, City, Age, Job
John, Doe, Johannesburg, 28, Technical Support
现在我需要复制City,因此输出应为:
Name, Surname, City, City Again, Age, Job
John, Doe, Johannesburg, Johannesburg, 28, Technical Support
该列需要放在那个将被复制的列之后。该值也取决于第一列。
答案 0 :(得分:5)
awk
可以轻松应对:
awk 'BEGIN{FS=OFS=", "} {$3 = $3 OFS $3} 1' file.csv
Name, Surname, City, City, Age, Job
John, Doe, Johannesburg, Johannesburg, 28, Technical Support
请注意,这可以在单个和短路命令中完成这项工作,该命令易于阅读,并且比管道命令更有效,包括调用cut
两次然后“粘贴”。
正如@codeforester在下面正确评论的那样,cut
不允许在输出中重复列;它用于剥离值。
答案 1 :(得分:0)
假设City
始终位于第3列,可以使用cut和paste命令。例如:
csv=path/to/somefile.csv
echo "$(paste -d',' <(cut -d',' -f1-3 $csv) <(cut -d',' -f3- $csv))" > "$csv"
注意:
path/to/quux.csv
变量的csv
部分应替换为.csv
文件的实际路径。City
列的新内容将写回同一源文件。<(...)
部分称为流程替换,通常在无法使用管道数据时使用。可以找到对它的一个很好的解释here。答案 2 :(得分:0)
前段时间,我写了一个bash函数来插入数组元素:
function array_insert {
# options: arrayname index [value]
if ! declare -p "$1" 2>/dev/null | grep -q '^declare -a'; then
printf '%s: not an array: %s\n' "$0" "$1" >&2
return 1
fi
local -n source="$1"
local -a indices=( "${!source[@]}" )
for ((i=${#indices[@]}-1; i>=$2; i--)) ; do
source[$((i+1))]="${source[$i]}"
done
if [ -n "$3" ]; then
source[$2]="$3"
fi
}
加载此功能后,您可以执行以下操作:
while read line; do
IFS=, declare a=( $line ) # assign the line's fields to an array,
array_insert a 3 "${a[2]}" # insert the column in this line,
o=$(printf '%s,' "${a[@]}") # assemble your output,
printf '%s\n' "${o%,}" # remove the trailing comma.
done < input.txt
对我来说,这会使用您的输入提供以下输出:
Name, Surname, City, City, Age, Job
John, Doe, Johannesburg, Johannesburg, 28, Technical Support
请注意,在bash中,数组是从0
建立索引的,因此${a[2]}
是第三列。
答案 3 :(得分:0)
下面是小脚本,它有两个输入
以下是脚本
echo "Enter CSV File name "
read fileName
echo "Enter Column name to be duplicated "
read columnName
columnNumber=`head -1 $fileName | awk -v RS="," "/$columnName/{print NR;}"` #Identify Column number using column name
totalNumberOfColumn=`head -1 $fileName | awk -F',' '{print NF}'` #identify total number of column
str="" #Create empty variab str to print column number in awk
for ((i=1;i<=$totalNumberOfColumn;i++));
do
str="$str \$$i\",\""
if [ $i == $columnNumber ]
then
str="$str \$$i\",\""
fi
done
awk -F',' "{print ${str}}" $fileName | sed 's/,$//g' #Print all column inculding duplicate column
下面是文件内容,文件名是 data.csv
:cat data.csv
Name, Surname, City, Age, Job
John, Doe, Johannesburg, 28, Technical Support
复制列城市
的输出1:bash script.sh
Enter CSV File name
data.csv
Enter Column name to be duplicated
City
Name, Surname, City, City, Age, Job
John, Doe, Johannesburg, Johannesburg, 28, Technical Support
输出2:用于复制列名称
:bash script.sh
Enter CSV File name
data.csv
Enter Column name to be duplicated
Name
Name,Name, Surname, City, Age, Job
John,John, Doe, Johannesburg, 28, Technical Support