对于文件中的每一行,同步执行命令并保存到另一个文件的换行符
Posted
技术标签:
【中文标题】对于文件中的每一行,同步执行命令并保存到另一个文件的换行符【英文标题】:For each line in file execute command synchronously and save to newline of another file 【发布时间】:2014-12-04 19:42:31 【问题描述】:我有一个名为 Chktitle.sh
的 wget
脚本 -- 该脚本接受如下命令
$ Chktitle.sh "my url"
然后我有一个文件名url.txt
,其中包含超过 100 行的 url 和 ips 来检查网页标题。
然后我将results.txt
作为一个空白文件。
有什么方法可以对文件中的每一行执行如下重复操作:
Grab line1 from url.txt
-----
then execute Chktitle.sh "line1"
-----
Now save the result for line1 in results.txt
-----
Now goto Line2 ........
etc etc etc
我需要确保它只会在上一行完成后才执行下一行。 任何人都可以告诉我任何简单的方法来执行此操作吗?我很乐意使用 Perl、sh,并考虑使用其他语言..
chktitle.sh
的内容:
#!/bin/bash
string=$1"/search/"
wget --quiet -O - $string \
| sed -n -e 's!.*<title>\(.*\)</title>.*!\1!p'
【问题讨论】:
我会说将整个事情放在一个 Perl 脚本中会更好。 (Perl 因为我比 shell 更擅长它。)Chktitle.sh
里面有什么?复杂吗?
不,像这样并不复杂
【参考方案1】:
也许这样的事情会有所帮助(前提是我理解正确):
while read line; do
/path/to/Chktitle.sh x"$line" >> results.txt;
done < /path/to/input.txt
对于/path/to/input.txt
中的每一行,执行您的脚本并将输出 (>>
) 附加到results.txt
。
当然,你总是可以在你的 while 循环中添加额外的语句:
while read line; do
# Initialise var to output of chktitle
var=$(/path/to/Chktitle.sh x"$line");
# Add conditions
if [ "$var" = "google" ]; then
echo "google" >> result.txt;
else
echo "not google" >> result.txt;
fi
done < /path/to/input.txt
【讨论】:
这看起来像我需要的,我忘了问你也能做吗?如果 chktitle 结果 = google 保存到结果,则不执行任何操作并转到下一个 url @LeoBishop:已编辑。希望有帮助。 Tbh,还将添加一个测试以验证结果文件是否存在。一个好的起点可能是这样(对不起,缺少换行符):base="/tmp"; result="result.txt"; if [ ! -d "$base" ]; then mkdir -p "$base"; touch "$base/$result"; fi
或者目录可能存在但文件不存在,或者它们可能都存在并且您想在每次运行时粉碎 result.txt,等等第四……
在循环外进行重定向会更有效率。所以while do; ...; done <input >output
【参考方案2】:
在 Perl 中你可以这样做:
use warnings;
use strict;
use LWP::Simple;
my $inputFile = 'url.txt';
open (my $fh, '<', $inputFile) or die "Could not open file '$inputFile': $!\n";
while (<$fh>)
my $url=chomp;
my $str=get($url);
if (! defined $str)
warn "Could not find page '$url'\n";
next;
my ($title)=$str=~ m<title>(.*?)</title>s;
if (! defined $title)
warn "No title in document '$url'\n";
next;
print "$title\n";
close ($fh);
【讨论】:
【参考方案3】:cat url.txt | xargs -I ./Chktitle.sh >> results.txt
参见xargs
,尤其是-I
开关。
此xargs
调用将逐行读取输入 (url.txt
) 并调用 ./Chktitle.sh
并将每个这样的读取行作为参数。
是读取行的占位符。你也可以写
cat url.txt | xargs -Ifoo ./Chktitle.sh foo >> results.txt
(以foo
作为占位符)但 是通常用于
xargs
的占位符。
【讨论】:
【参考方案4】:您可以使用以下 2 个参数创建脚本
脚本在命令行上的工作原理
< script > < path to url file > <path to excuting script>
。 代码分解如下并有解释
第 1 步
#!/bin/bash
rm -f "/root/Desktop/result.txt 2> /dev/null
删除任何名为 result.txt 的文件,以便我可以创建一个新的空白文件
第 2 步
while read -r my_url; do
"$2" "$my_url" >> "/root/Desktop/result.txt"
done < "$1"
设置一个 while do 循环来读取 url 文件中的所有行(称为“$1”)。
读取的每一行都保存为“my_url”。
循环获取您的脚本脚本 (Chktitle.sh - $2),后跟称为“my_url”的行,并在命令行上执行它并将输出重定向到 result.txt。这是为每一行完成的。
现在让我们将所有代码汇总到一个脚本中,如下所示
#!/bin/bash
rm -f result.txt 2> /dev/null
while read -r my_url; do
"$2" "$my_url" >> "/root/Desktop/result.txt"
done < "$1"
【讨论】:
您为什么要编写root
层次结构,为什么root
首先要有Desktop
?令人不安。以上是关于对于文件中的每一行,同步执行命令并保存到另一个文件的换行符的主要内容,如果未能解决你的问题,请参考以下文章
通过shell脚本实现读取文件新增的每一行并追加到另一台服务器的文件末尾