回答
这比看起来更难。问题是如何保持文件句柄。
解决的办法是创建另一个新的文件句柄,其工作方式与stdin
(文件句柄0)相似,但是独立,然后根据需要从中读取。
#!/bin/bash
# Create dummy input
for i in $(seq 1 10) ; do echo $i >> input-file.txt ; done
# Create new file handle 5
exec 5< input-file.txt
# Now you can use "<&5" to read from this file
while read line1 <&5 ; do
read line2 <&5
read line3 <&5
read line4 <&5
echo "Four lines: $line1 $line2 $line3 $line4"
done
# Close file handle 5
exec 5<&-
只需使用一个for
循环:
for i in $(seq 1 $N) ; do read line ; lines+=$line$'\n' ; done
在bash版本4,您还可以使用mapfile
命令。
是的,在bash中没有明确的“读取N行”。你必须用值串联来构造它。 @choroba在这里的正确轨道,但需要提供输入源和管理多个输入通道(每N次读取重置“行”)。 Awk确实是针对这些问题而设计的(但是没有明确的'读取N行'函数),您需要在awk中用'NR'变量管理N行。 Sed也可以工作,但实际上会很丑陋,并且需要大量的搞乱才能使N通用而不是硬编码处理。祝你们好运。 – shellter
我试过像:for i in $(seq 1 4); do read line <101127_2_aa_1.fastq; lines + = $ line $'\ n';完成 但似乎没有用... – user815408
其实,如何提供输入? – user815408
根据你想要做的,你可以存储以前的行。
LINE_COUNT=0
PREVLINE1=""
PREVLINE2=""
while read LINE
do LINE_COUNT=$(($LINE_COUNT+1));
if [[ $LINE_COUNT == 3 ]]; then
LINE_COUNT=0
# do whatever you want to do with the 3 lines
done
PREVLINE2="$PREVLINE1"
PREVLINE1="$LINE"
done
done < $FILE_IN
我不认为有一种方法在bash做它本身,而是一个可以这样做创建一个方便的功能:
#
# Reads N lines from input, keeping further lines in the input.
#
# Arguments:
# $1: number N of lines to read.
#
# Return code:
# 0 if at least one line was read.
# 1 if input is empty.
#
function readlines() {
local N="$1"
local line
local rc="1"
# Read at most N lines
for i in $(seq 1 $N)
do
# Try reading a single line
read line
if [ $? -eq 0 ]
then
# Output line
echo $line
rc="0"
else
break
fi
done
# Return 1 if no lines where read
return $rc
}
有了这个可以很容易地遍历N-通过执行类似
while chunk=$(readlines 10)
do
echo "$chunk" | ... # Whatever processing
done
在这个循环$块包含10条输入线路在每次迭代中,除了最后一个,其中将包含输入的最后几行,这可能是小于数据线块10但总是超过0.
我真的很喜欢这个解决方案,但你怎么称呼它?你如何传递一个文件名? – jasonmclose
上面的while循环将从标准输入读取。如果你想输入一个文件给它,只需要将它输入到标准输入。 – albarji
啊。所以'cat $ filename | readlines 10'? – jasonmclose
我想出了一些非常类似于@ albarji的答案,但更简洁。
read_n() { for i in $(seq $1); do read || return; echo $REPLY; done; }
while lines="$(read_n 5)"; do
echo "========= 5 lines below ============"
echo "$lines"
done < input-file.txt
的read_n
功能将读取stdin
$1
线(使用重定向,使其从文件中读取,就像内置read
命令)。由于read
的退出码保持不变,您可以在循环中使用read_n
,如上例所示。
虽然选定的答案有效,但确实不需要单独的文件句柄。只需在原始句柄上使用读命令就可以正常工作。
下面是两个例子,一个是字符串,一个具有一个文件:
# Create a dummy file
echo -e "1\n2\n3\n4" > testfile.txt
# Loop through and read two lines at a time
cat testfile.txt | while read -r ONE; do
read -r TWO
echo "ONE: $ONE TWO: $TWO"
done
# Create a dummy variable
STR=$(echo -e "1\n2\n3\n4")
# Loop through and read two lines at a time
echo "$STR" | while read -r ONE; do
read -r TWO
echo "ONE: $ONE TWO: $TWO"
done
运行上面作为脚本将输出(对于两个环路相同的输出):
ONE: 1 TWO: 2
ONE: 3 TWO: 4
ONE: 1 TWO: 2
ONE: 3 TWO: 4
这个答案值得的方式比它有更多的信用。 –
也许更新这个使用更有效的方式来读取文件[这里](https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash) (不用调用'cat')。 – hnefatl
我知道你问庆典,但我很惊讶,这一点也适用zsh
#!/usr/bin/env zsh
cat 3-lines.txt | read -d\4 my_var my_other_var my_third_var
Unfortunatel Ÿ,这不适用于bash
,至少我试过的版本。
“魔术师”这里是-d\4
(这并不在bash工作),即设置行分隔符是EOT
字符,它会在你cat
的末尾。或者任何产生输出的命令。
如果你想读的N
项的数组,bash有readarray
和mapfile
可以读取与N
线文件,并保存每一行的阵列中的一个位置。
编辑
一些尝试后,我才发现,这个工程使用bash:
$ read -d# a b
Hello
World
#
$ echo $a $b
Hello World
$
但是,我不能让{ cat /tmp/file ; echo '#'; } | read -d# a b
工作:(
最简单的方法 - 相当不言自明,它类似于@Fmstrat提供的方法,除了第二个read
声明之前是do
。
while read first_line; read second_line
do
echo "$first_line" "$second_line"
done
您可以通过管道输入多给它使用:
seq 1 10 | while read first_line; read second_line
do
echo "$first_line" "$second_line"
done
输出:
1 2
3 4
5 6
7 8
9 10
有人知道吗?怎么运行的????? –
随着Bash≥4可以使用mapfile
像这样:
while mapfile -t -n 10 ary && ((${#ary[@]})); do
printf '%s\n' "${ary[@]}"
printf -- '--- SNIP ---\n'
done < file
这是一次读取10行。
不能相信这个优秀的答案是投票表决++ – anubhava
这似乎是最有效和最优雅的方法,因此应该是被接受的答案。如果添加了对&&(($ {#ary [@]}))的解释,那就太好了。 – codeforester
的echo
模拟了两行输入一个文件,如果需要使用head -2
paste
前:
IFS=\; read A B < <(echo -en "X1 X2\nY1 Y2\n" | paste -s -d\;)
如果你想读的环行,并创建对,并线都只有一个字在其中使用:
while read NAME VALUE; do
echo "$NAME=$VALUE";
done < <(echo -en "M\n1\nN\n2\nO\n3\n" | xargs -L2 echo)
这里做的另一种方式:
//This will open the file and users can start adding variables.
cat > file
//After finished ctrl + D will close it
cat file|while read line;
do
//do some stuff here
done
mapfile -n通过Bash读取超出分配给数组最后一行的额外行。固定在4.2.35中
这是如何回答这个问题的?我将此举标记为_不是答案,但该标志因此消息被拒绝:_flags不应用于指示技术上的不准确或完全错误的答案。 –
- 1. 一次只能读取N行(MySQL)
- 2. n次读写行
- 3. 读取n次行的ArrayList的一部分?
- 4. 如何从bash中的文本文件读取第n行?
- 5. Bash:读取Localizable.strings的每一行
- 6. bash:读取文件中的第一个'n'条目
- 7. 在bash中多次读取stdin
- 8. 如何通过使用pyserial一次读取一行
- 9. 如何在unix中使用C shell一次读取一行
- 10. 在C中一次读取一行
- 11. SqlDataReader每隔一行读取一次?
- 12. 阅读地图一次N键
- 13. 一次读取inputStream
- 14. C - 无需使用fgets/getline,一次从文件1行读取
- 15. 在Python中一次读取stdin行
- 16. Fortran read()读取最后一行两次?
- 17. Python - 一次从文件读取1000行
- 18. 一次从文件中读取两行
- 19. 使用bash读取一个文件,然后从单词执行命令提取
- 20. 读取在bash
- 21. 想要读取一行文件从行(1)到行(n)在php
- 22. Oracle使用游标读取第n列
- 23. 打破第N次执行一行
- 24. bash:嵌套交互式读取循环中也使用读取
- 25. bash-删除\ n每三行
- 26. 平均每第n行bash
- 27. MATLAB:如何读取文本文件的每一行第N行?
- 28. 提取第N次出现的行号
- 29. 如何在makefile中使用\ n(新行)使用bash脚本
- 30. 使用bash脚本从文件中读取行
也许我误解了这个问题,但即使没有输入的诡计,只是调用read read也可以很好地工作。 – Tgr
再次准备,我也不知道为什么我解释了如何创建一个新的文件句柄,而不是使用stdio: -/ –
感谢你们,我用它作为我解决方案的基础。这工作,但额外的文件句柄不是必需的。请参阅下面的解决方案,但是不需要第二个句柄。 – Fmstrat