回答
這比看起來更難。問題是如何保持文件句柄。
解決的辦法是創建另一個新的文件句柄,其工作方式與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次讀寫行
- 4. Python:用islice一次讀取N個行數的問題
- 5. bash/shell不止一次讀取LINE
- 6. 如何在bash中一次讀取和運行10行命令?
- 7. Python:一次在列表中讀取n行
- 8. 讀取n次行的ArrayList的一部分?
- 9. 一次讀取4行
- 10. 讀取/ RDS使用bash
- 11. PHP + MYSQL +獲取n行一次
- 12. 讀一個文本文件,每次有一行n個行
- 13. 如何從bash中的文本文件讀取第n行?
- 14. Bash:讀取Localizable.strings的每一行
- 15. bash腳本無法讀取第一行
- 16. bash:讀取文件中的第一個'n'條目
- 17. Haskell第n行讀取
- 18. bash讀取循環只讀取輸入變量的第一行
- 19. 如何通過使用pyserial一次讀取一行
- 20. 如何在unix中使用C shell一次讀取一行
- 21. 使用XmlHttpResponse對象一次讀取一行
- 22. 在bash中多次讀取stdin
- 23. 一次讀取文本文件一行
- 24. 在C中一次讀取一行
- 25. SqlDataReader每隔一行讀取一次?
- 26. 讀取一條線,在BASH
- 27. 讀取一行,並一次讀取三個字母C
- 28. Bash,用跳線逐行讀取文件
- 29. 用bash腳本逐行讀取文件
- 30. 閱讀地圖一次N鍵
也許我誤解了這個問題,但即使沒有輸入的詭計,只是調用read read也可以很好地工作。 – Tgr
再次準備,我也不知道爲什麼我解釋瞭如何創建一個新的文件句柄,而不是使用stdio: -/ –
感謝你們,我用它作爲我解決方案的基礎。這工作,但額外的文件句柄不是必需的。請參閱下面的解決方案,但是不需要第二個句柄。 – Fmstrat