对于文件中的每一行,同步执行命令并保存到另一个文件的换行符

Posted

技术标签:

【中文标题】对于文件中的每一行,同步执行命令并保存到另一个文件的换行符【英文标题】:For each line in file execute command synchronously and save to newline of another file 【发布时间】:2014-12-04 19:42:31 【问题描述】:

我有一个名为 Chktitle.shwget 脚本 -- 该脚本接受如下命令

$ 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 中的每一行,执行您的脚本并将输出 (&gt;&gt;) 附加到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 &lt;input &gt;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脚本实现读取文件新增的每一行并追加到另一台服务器的文件末尾

python 文件单行循环读取的坑(一个程序中,文件默认只能按行循环读取一次,即使写到另一个循环里,它也只读取一次)

如何将文件(IN C)中的每一行保存在变量中? :)

如何为文件的每一行运行命令?

将 Spark Dataframe 中的每一行保存到不同的文件中