如何将表达式分配给读取行的变量?
How can I assign expressions to a variable for read line?
我有一个 bash while read line
块从 $filename
指定的文本文件中读取:
IFS=''
while read -r line
do
...
done < $filename
我不想每次都读取整个文件,而是想根据提供给脚本的参数在重定向中提供不同的输入。
- 整个文件:
done < "$filename"
- 从第 x 行开始:
done < <(tail -n +"$x" "$filename")
- x 行到 y 行:
done < <(tail -n +"$x" "$filename" | head -n "$y")
- 从第 y 行开始:
done < <(head -n "$y" "$filename")
如何提前将这些输入分配给变量以供 while 循环读取?
我的输入文件大约有 4GB,有一些 58M 行(所有行都有不同的长度),并且可能会不时地增长或缩小。读取 https://unix.stackexchange.com/questions/47407/cat-line-x-to-line-y-on-a-huge-file 似乎 tail | head
是从文件中间读取的最快方法,因此考虑到文件大小,我故意避免 awk
和 sed
大部分。
我可能会将所有这些作为循环条件的一部分来处理,并带有一个明确维护的行计数器。
start=10
end=30
i=0
while ((i <= end )) && IFS= read -r line; do
(( i++ >= start )) || continue
...
done < "$filename"
但是,如果您可能在开头跳过大量行,使用 sed
可能更有效
while IFS= read -r line; do
...
done < <(sed -n "$start,$stop p" "$filename")
或awk
:
while IFS= read -r line; do
...
done < <(awk -v start "$start" -v end "$end" 'NR >= start && NR <= end' "$filename")
这就提出了一个问题,即 while
循环的主体有多少可以移入 awk
本身。
您的数据太大,无法完整读取。好消息是一个进程替换的内容是一个shell脚本,所以你可以这样写:
while IFS= read -r line; do
...
done < <(
if [[ $x && $y ]]; then tail -n +"$x" "$filename" | head -n "$y"
elif [[ $x ]]; then tail -n +"$x" "$filename"
elif [[ $y ]]; then head -n "$y" "$filename"
else cat "$filename"
fi
)
我不喜欢进程替换的一件事是代码遵循输入它的循环。要是先出现就好了。我认为这会起作用,但未经测试:
# set up file descriptor 3
exec 3< <(
if [[ $x && $y ]]; then tail -n +"$x" "$filename" | head -n "$y"
elif [[ $x ]]; then tail -n +"$x" "$filename"
elif [[ $y ]]; then head -n "$y" "$filename"
else cat "$filename"
fi
)
# iterate over lines read from fd 3
while IFS= read -u3 -r line; do
...
done
# close fd 3
exec 3<&-
我有一个 bash while read line
块从 $filename
指定的文本文件中读取:
IFS=''
while read -r line
do
...
done < $filename
我不想每次都读取整个文件,而是想根据提供给脚本的参数在重定向中提供不同的输入。
- 整个文件:
done < "$filename"
- 从第 x 行开始:
done < <(tail -n +"$x" "$filename")
- x 行到 y 行:
done < <(tail -n +"$x" "$filename" | head -n "$y")
- 从第 y 行开始:
done < <(head -n "$y" "$filename")
如何提前将这些输入分配给变量以供 while 循环读取?
我的输入文件大约有 4GB,有一些 58M 行(所有行都有不同的长度),并且可能会不时地增长或缩小。读取 https://unix.stackexchange.com/questions/47407/cat-line-x-to-line-y-on-a-huge-file 似乎 tail | head
是从文件中间读取的最快方法,因此考虑到文件大小,我故意避免 awk
和 sed
大部分。
我可能会将所有这些作为循环条件的一部分来处理,并带有一个明确维护的行计数器。
start=10
end=30
i=0
while ((i <= end )) && IFS= read -r line; do
(( i++ >= start )) || continue
...
done < "$filename"
但是,如果您可能在开头跳过大量行,使用 sed
while IFS= read -r line; do
...
done < <(sed -n "$start,$stop p" "$filename")
或awk
:
while IFS= read -r line; do
...
done < <(awk -v start "$start" -v end "$end" 'NR >= start && NR <= end' "$filename")
这就提出了一个问题,即 while
循环的主体有多少可以移入 awk
本身。
您的数据太大,无法完整读取。好消息是一个进程替换的内容是一个shell脚本,所以你可以这样写:
while IFS= read -r line; do
...
done < <(
if [[ $x && $y ]]; then tail -n +"$x" "$filename" | head -n "$y"
elif [[ $x ]]; then tail -n +"$x" "$filename"
elif [[ $y ]]; then head -n "$y" "$filename"
else cat "$filename"
fi
)
我不喜欢进程替换的一件事是代码遵循输入它的循环。要是先出现就好了。我认为这会起作用,但未经测试:
# set up file descriptor 3
exec 3< <(
if [[ $x && $y ]]; then tail -n +"$x" "$filename" | head -n "$y"
elif [[ $x ]]; then tail -n +"$x" "$filename"
elif [[ $y ]]; then head -n "$y" "$filename"
else cat "$filename"
fi
)
# iterate over lines read from fd 3
while IFS= read -u3 -r line; do
...
done
# close fd 3
exec 3<&-