【问题标题】:File Manipulation Loop文件操作循环
【发布时间】:2012-07-20 11:50:11
【问题描述】:

好的,这个问题有两个方面:1)实际的文件操作位 2)在 unix 中循环这个操作

第 1 部分)

我有两个文件:

文件_1

a b
c d
e f
g h

和文件_2

A B
C D
E F
G H
I J

我想(首先)得到以下结果:

a b
A B
>
c d
A B
>
e f
A B
>
g h
A B

...并将此输出保存到 outfile1。

我想我必须使用 awkcut 和/或 paste 之类的东西,但我无法全部使用在一起。

第 2 部分)

然后我想对 File_2 中的所有行循环这个操作(注意 File_1 中的行数与 File_2 中的不同),这样我最终得到 5 个输出文件,其中 outfile2 将是:

a b
C D
>
c d
C D
>
e f
C D
>
g h
C D

而 outfile3 将是:

a b
E F
>
c d
E F
>
e f
E F
>
g h
E F

等等

目前我正在使用 bash。提前感谢您的帮助!

【问题讨论】:

  • 我对 Unix 编码很陌生,所以目前我能做的最复杂的事情是 awk NR==51 { print $3, $4; exit }' < input 所以我的问题是(基本上)我如何处理我的输入使用 Unix 获取我的输出文件的文件
  • 请提出您的问题in your question

标签: bash unix loops awk


【解决方案1】:

这可以通过bash 重定向来完成:

i=1

while read f2; do
  while read f1; do
    echo "$f1"
    echo "$f2"
    echo ">"
  done < File_1 | head -n -1 > output$i
  (( i++ ))
done < File_2

head -n -1 避免在每个 output$i 文件的末尾使用单独的分隔符。

【讨论】:

  • 比我的更干净,我无法想象 bash 中的嵌套循环)))
  • 我同意这一点。当心性能问题。 perl 解决方案会快很多,但只有在文件变大或磁盘速度慢时才会受到伤害:)
  • 确实,这个解决方案在大输入时表现不佳。
  • 感谢您的回答 - 来自 Matlab 背景,这对我来说是最直观的答案。
【解决方案2】:

例如制作 outfile_3(with E F):

x=$(sed -n '3p' File_2)
awk "{ printf \"%s\\n%s\\n>\\n\", \$0, \"$x\" }" File_1 > outfile_3

在第一行 '3p' 删除第三行
现在让我们循环执行:

(( i = 1 ))
while read line
do
  awk "{ printf \"%s\\n%s\\n>\\n\", \$0, \"$line\" }" File_1 > "outfile_$i"
  (( i++ ))
done < File_2

【讨论】:

  • 谢谢!这正是我想要的。
【解决方案3】:
sort -m -f file1 file2 | uniq -i --all-repeated=separate

看起来很近。但是,在第二次阅读时,我认为您想要更像这个 perl 脚本的东西:

use strict;
use warnings;

open(my $FILE1, '<file1') or die;

my $output = 0;

while (my $a = <$FILE1>)
{
    $output++;
    open(my $OUT, ">output$output");
    open(my $FILE2, '<file2') or die;

    print $OUT "$a$_---\n" foreach (<$FILE2>);

    close $FILE2;
    close $OUT;
}

close $FILE1;

这将创建输出文件output1output12output3output...,与 file1 中的行数一样多

【讨论】:

  • 针对带有bashawk 标记的问题的基于Perl 的解决方案...?
  • 感谢您花时间回答我的问题,但正如 stakx 所暗示的,这对我来说不是很有用 - 用 perl 重写我的脚本超出了我的能力。
  • 不需要重写东西。我的印象是这是一个新剧本。您可以从 bash 中使用它,例如 awk :)
【解决方案4】:

一个 awk one 班轮:

     awk 'NR==FNR{a[NR]=$0;l=NR;next;} {b[FNR]=$0;}
    END{f=1; for(x=1;x<=FNR;x++){for(i=1;i<=length(a);i++){
printf "%s\n%s\n%s\n", a[i],b[x],">" > "output"f }f++;}}' f1 f2

测试:

kent$  head f1 f2
==> f1 <==
a b
c d
e f
g h

==> f2 <==
A B
C D
E F
G H
I J


kent$  awk 'NR==FNR{a[NR]=$0;l=NR;next;} {b[FNR]=$0;}
END{f=1; for(x=1;x<=FNR;x++){for(i=1;i<=length(a);i++){printf "%s\n%s\n%s\n", a[i],b[x],">" > "output"f }f++;}}' f1 f2

kent$  head -30 out*
==> output1 <==
a b
A B
>
c d
A B
>
e f
A B
>
g h
A B
>

==> output2 <==
a b
C D
>
c d
C D
>
e f
C D
>
g h
C D
>

==> output3 <==
a b
E F
>
c d
E F
>
e f
E F
>
g h
E F
>

==> output4 <==
a b
G H
>
c d
G H
>
e f
G H
>
g h
G H
>

==> output5 <==
a b
I J
>
c d
I J
>
e f
I J
>
g h
I J
>

【讨论】:

  • 恕我直言,如果您向 OP 解释它的工作原理和原因,您的解决方案会更好,尤其是因为他是“Unix 编码新手”。
  • 正如 stakx 所说,尽管我真的很喜欢你的回答,但这对我来说真的很难解构。这也意味着当我遇到错误时(我会这样做):awk: syntax error at source line 2 context is END{f=1; for(x=1;x&lt;=FNR;x++){for(i=1;i&lt;=length(a);i++){printf "%s\n%s\n%s\n", a[i],b[x],"&gt;" &gt; &gt;&gt;&gt; "output"f &lt;&lt;&lt; }f++;}} awk: illegal statement at source line 2 我不知道如何解决问题。还是谢谢!
猜你喜欢
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
  • 2012-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多