循环遍历Bash中的所有列

时间:2016-10-23 17:03:11

标签: bash csv

我的目标是读取一个.csv文件,反转每一行,然后将结果写出到另一个文件,我成功地设法做到了。

我的代码的问题是我必须指定csv文件中的列数(f1,f2,f3等)。如何在没有指定我不知道.csv文件内容的场景中的列数的情况下,让它遍历所有列?

PS:我在尝试之前尝试在论坛上寻找答案,但我找不到任何有用的东西!

input="/path/to/file"
while IFS=',' read -r f1 f2 f3 f4 f5 f6 f7
do 
    echo "$f7 $f6 $f5 $f4 $f3 $f2 $f1" >> output.csv
done < "$input"

1 个答案:

答案 0 :(得分:3)

使用 .range::before{ content: ''; display: inline-block; width: 15px; height: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px; border-radius: 15px; background-color: #69b6d5; } 不仅可以更轻松地处理可变数量的列,还可以更快

awk
  • awk -F, '{ for(i=NF; i>=2; --i) printf "%s ", $i; print $1 }' "$input" > output.csv 告诉-F,将输入分为逗号

  • awk遍历所有字段索引,从for(i=NF; i>= 2; --i)(输入字段数)向 2nd 字段倒计时。

  • NF引用其(基于1的)索引为$i的字段(列)。

  • i是(隐式)循环体(为了清楚起见,您可以将其括在printf "%s "中),并打印带有尾随空格的手头字段,如问题代码中所示。
    请注意,{ ... }printf不同,默认会自动附加换行符。

  • 最后,在循环之后,print打印第一个字段,然后输出换行符(print $1)以完成输出行(\n }是输出记录分隔符\n的默认值。

如果您需要纯Bash解决方案慢得多):

ArraysORS相结合是解决方案:

read -a

注意:

  • 输出重定向while IFS= read -r line; do # read input line by line # Split line into fields and read into array. IFS=, read -ra fields <<<"$line" # Loop over fields from the back, down to the 2nd. for (( i = ${#fields[@]} - 1; i >= 1; --i )); do printf '%s ' "${fields[i]}" done # Print 1st field and complete line (append line). printf '%s\n' "${fields[0]}" done < "$input" > output.csv 应用于整个循环 (就像输入重定向,> output.csv),这比在循环中使用< "$input" 更简单,更有效(在后一种情况下,你也有预先截断>> output.csv以确保不会附加预先存在的内容。

  • output.csv数组基于bash - ,而基于0的数组则从索引awk开始。