[英]Write the outcome of a for loop in multiple files in a single file in shell
[英]write output to multiple files in shell
我在File_A中將135個文檔存儲為135行(因此每行是一個長文本),我在File_B中有15個短語。 我需要使用File_B中的匹配短語從File_A中提取一個句子及其之前的句子。 File_A-Line_1中提取的句子應輸出到新文件File_1。 類似地,從File_A-Line_2中提取的句子應該輸出到新文件File_2,依此類推,直到我從所有行中提取匹配的句子。 我用以下代碼完成了這個
i=1
while read line; do
while read row; do
cat "$line" | sed 's/\./.\n/g' | grep -i -B 1 "$row" | tr -d '\n' | sed 's/--/\n/g' >> file_$i
done < $2
$i = $i+1;
done < $1
這里的問題是,輸出打印到控制台但不打印到新文件。 有人可以幫助我實現我的錯誤。
謝謝
我認為這會奏效
i=1
while read line; do
while read row; do
echo "$line" | sed 's/\./.\n/g' | grep -i -B 1 "$row" | tr -d '\n' | sed 's/--/\n/g' >> file_$i
done < $2
$i = $i+1;
done < $1
a=0
while read line; do
a=$(($a+1));
while read row; do
echo "$line" | sed 's/\./.\n/g' | grep -i -B 1 "$row" | tr -d '\n' | sed 's/--/\n/g' >> file_$a done < $2 done < $1
這不是你在shell中增加變量的方式:
$i = $i + 1
而是嘗試運行名稱為$i
的當前值的命令。 你要這個:
let i=i+1
或者,更簡潔地說,
let i+=1
這可能不是問題,但這是一個問題,它可能導致奇怪的行為。
我看到的另一件事是文件名周圍缺少引號( "$1"
, "$2"
)。
另外,如果每一行都是文件名,則不需要cat
; 做就是了
<"$line" sed ...
如果每一行都是文件的內容而不是名稱,則cat
完全錯誤,因為它試圖找到一個名稱是大文本長的文件。 您可以使用此代替:
<<<"$line" sed ...
編輯此外,如果fileB中沒有那么多行,您可能可以避免對fileA中列出的每個文件一遍又一遍地讀取它。 只需立即將所有fileB讀入內存:
IFS=$'\n' rows=($(<"$2"))
let i=0
while read line; do
for row in "${rows[@]}"; do
<<<"$line" sed 's/\./.\n/g' | grep -i -B 1 "$row" |
tr -d '\n' | sed 's/--/\n/g' >> file_$i
done
let i+=1
done < "$1"
事實上,你甚至可以在一個grep中完成它:
pat=''
while read row; do
pat="${pat:+$pat|}$row"
done <"$2"
let i=0
while read line; do
<<<"$line" sed 's/\./.\n/g' | egrep -i -B 1 "$pat" |
tr -d '\n' | sed 's/--/\n/g' >"file_$i"
let i+=1
done < "$1"
修復前面提到的問題(重新增加i
和誤用cat
)會導致類似以下內容。 注意,行date > file_$i
用於調試,以確保每個輸出文件在測試開始時都是新的。 :
運算符是無操作符。 形式<<<
引入了“here-doc”。 如果$lines
的內容是文件名,而不是問題中指定的文檔,請使用<"$lines"
代替<<<"$lines"
。
#!/bin/bash
i=1
while read line; do
date > file_$i
while read row; do
sed 's/\./.\n/g' <<< "$line" | grep -iB1 "$row" | tr -d '\n' | sed 's/--/\n/g' >> file_$i
done < $2
: $((i++))
done < $1
給定splitdoc.data包含以下內容:
This is doc 1. I am 1 fine. How are you, 1.? Ok. Hello 1.-- Go away now.
This is doc 2. I am 2 fine. How are you, 2.? Ok. Hello 2.-- Go away now.
This is doc 3. I am 3 fine. How are you, 3.? Ok. Hello 3.-- Go away now.
This is doc 4. I am 4 fine. How are you, 4.? Ok. Hello 4.-- Go away now.
和splitdoc.tags具有以下內容:
How are you
Go away now
然后命令
./splitdoc.sh splitdoc.data splitdoc.tags ; head file_*
生產:
==> file_1 <==
Fri Oct 26 19:42:00 MDT 2012
I am 1 fine. How are you, 1. Hello 1.
Go away now.
==> file_2 <==
Fri Oct 26 19:42:00 MDT 2012
I am 2 fine. How are you, 2. Hello 2.
Go away now.
==> file_3 <==
Fri Oct 26 19:42:00 MDT 2012
I am 3 fine. How are you, 3. Hello 3.
Go away now.
這個清楚嗎? 如果沒有,請對其進行評論,然后我將對其進行編輯。 Bash輸出重定向示例:
echo "some text" >file.txt;
#here we add on to the end of the file instead of overwriting the file
echo "some additional text" >>file.txt;
#put something in two files and output it
echo "two files and console" | tee file1.txt | tee file2.txt;
#put something in two files and output nothing
echo "just two files" | tee file1.txt >file2.txt;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.