57

我想知道如何csv在 bash 脚本中从第二行到文件末尾读取文件的每一行。

我知道如何在 bash 中读取文件:

while read line
 do   
   echo -e "$line\n"
done < file.csv

但是,我想从第二行到文件末尾读取文件。我怎样才能做到这一点?

4

7 回答 7

73
tail -n +2 file.csv

手册页

-n, --lines=N
     output the last N lines, instead of the last 10
...

If the first character of N (the number of bytes or lines)  is  a  '+',
print  beginning with the Nth item from the start of each file, other-
wise, print the last N items in the file.

在英语中,这意味着:

tail -n 100打印最后 100 行

tail -n +100打印从第 100 行开始的所有行

于 2013-01-01T12:09:43.827 回答
19

简单的解决方案sed

sed -n '2,$p' <thefile

2您希望从中读取的行数在哪里。

于 2013-01-01T12:00:54.637 回答
11

否则(纯 bash)...

{ for ((i=1;i--;));do read;done;while read line;do echo $line;done } < file.csv

写得更好:

linesToSkip=1
{
    for ((i=$linesToSkip;i--;)) ;do
        read
        done
    while read line ;do
        echo $line
        done
} < file.csv

即使linesToSkip == 0 或linesToSkip > file.csv 的行数,这项工作也有效

编辑

更改(){}gniourf_gniourf 要求我考虑:第一个语法生成一个sub-shell,而{}不会。

当然,对于只跳过一行(作为原始问题的标题),循环for (i=1;i--;));do read;done可以简单地替换为read

{ read;while read line;do echo $line;done } < file.csv
于 2013-01-01T12:37:48.987 回答
7

有很多解决方案。我最喜欢的一个是:

(head -2 > /dev/null; whatever_you_want_to_do) < file.txt

您还可以使用tail跳过所需的行:

tail -n +2 file.txt | whatever_you_want_to_do
于 2013-01-01T12:07:21.937 回答
7

取决于你想对你的行做什么:如果你想将每个选定的行存储在一个数组中,最好的选择肯定是内置的mapfile

numberoflinestoskip=1
mapfile -s $numberoflinestoskip -t linesarray < file

将从第 2 行开始的文件的每一行存储file在数组中linesarray

help mapfile了解更多信息。

如果您不想将每一行存储在一个数组中,那么还有其他非常好的答案。

正如 F. Hauri 在评论中所建议的那样,这仅适用于您需要将整个文件存储在内存中的情况。

否则,你最好的选择是:

{
    read; # Just a scratch read to get rid (pun!) of the first line
    while read line; do
        echo "$line"
    done
} < file.csv

注意:不涉及/不需要子shell。

于 2013-01-01T12:43:21.730 回答
3

这将起作用

i=1
while read line
 do   
   test $i -eq 1 && ((i=i+1)) && continue
   echo -e "$line\n"
done < file.csv
于 2015-03-07T00:50:33.540 回答
1

我只会得到一个变量。

#!/bin/bash

i=0
while read line
do
    if [ $i != 0 ]; then
      echo -e $line
    fi
    i=$i+1
done < "file.csv"

上面的更新将检查$icsv 每一行上的变量。因此,如果您有数百万行的非常大的 csv 文件,它将占用大量 CPU 周期,这对大自然没有好处

可以使用以下一行来删除 CSV 文件的第一行,sed然后将剩余的文件输出到while循环。

sed 1d file.csv | while read d; do echo $d; done
于 2013-01-01T12:17:47.787 回答