我在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
问题在于,输出正在打印到控制台而不是新文件。有人可以帮助我实现我的错误。
谢谢
答案 0 :(得分: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
答案 1 :(得分: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"
答案 2 :(得分: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.
答案 3 :(得分:0)
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;