Unix 脚本读取文件并为每一行创建一个文件

Unix 脚本读取文件并为每一行创建一个文件

我有一个文件,我的任务是读取该文件并为每一行生成一个新文件。新生成的文件的名称应来自该行内容。

例子

该文件有这两行:

My name is hello world
My Name is not hello world

我想要的是:文件 1 应该有 1 条记录,该文件的名称是行的第四个字段

你到底是什么意思?

第一个文件应命名为:

hello

文件 2 应该有第二条记录,文件名应该是行的 4 个字段,但不是。

这里也是。你到底是什么意思?

第二个文件应命名为:

not

答案1

$cat mainfile
My name is hello world
My Name is not hello world

bash

#!/bin/bash
cat mainfile | while IFS= read line ;do 

name=$(echo ${line} | awk '{print $4}')

echo "${line}" >> ${name} 
done

csh

#!/bin/csh
foreach line ( "`cat mainfile`" )
set name = `echo ${line} | awk '{print $4}'`

    echo "${line}" >> $name
end

为了为主文件中的所有单词创建文件

#!/bin/bash
cat mainfile | while IFS= read line ;do

     for word in $line; do

   echo "${line}" >> ${word} 
  done
done

答案2

文件的行应写入名称取自第四个空格分隔字段的文件中。 “记录”一词指的是一行。 “列”一词有时用来代替“字段”,这里可以使用“单词”一词而不是“字段”。 “记录”和“字段”都比“行”和“列”(或“字”)更通用。特别是,行是换行符分隔的记录,“字段”通常是记录内以空格分隔的列或单词。

awk

awk '{ print >$4 }' <file.txt

这将为print输入文件中的每一行运行该语句一次file.txt。这>$4意味着输出被重定向到由该行中的第四个字段命名的文件。对于第一行,这将创建文件hello,对于第二行,这将创建文件not

$ cat hello
My name is hello world
$ cat not
My Name is not hello world

如果文件中存在更多行,则每行都将写入由其第四个字给出的文件中。如果两条线有相同的第四个字,两行将被写入同一个文件。

如果一行少于四个字,则会产生错误。

awk除非另有说明,否则使用换行符作为默认记录分隔符,并使用空格(制表符或空格)作为字段分隔符。


先进性awk

在程序中执行此类重定向时awkawk将保持文件打开状态,直到读取所有数据后退出。每个打开的文件都需要一个文件描述符,并且文件描述符的数量有限。如果许多必须写入文件,最好显式关闭文件:

awk '{ print >>$4; close($4) }' <file.txt

在这里,我们打开输出进行追加(而不是截断和覆盖),将当前行写入文件并关闭文件。当第二次打开同一文件进行输出时(因为字段 4 恰好在两行或更多行中相同),将附加数据。如果我们使用>$4,新数据就会覆盖旧数据。这在顶部的第一个程序中不是问题,因为我们从未明确关闭文件。

脚本(或任何调用awk程序的程序)必须在运行之前将输出文件设置为空或不存在,具体取决于具体情况。

删除文件hellonot,并运行上述命令三次:

$ rm hello not
$ awk '{ print >>$4; close($4) }' <file.txt
$ awk '{ print >>$4; close($4) }' <file.txt
$ awk '{ print >>$4; close($4) }' <file.txt
$ cat hello
My name is hello world
My name is hello world
My name is hello world
$ cat not
My Name is not hello world
My Name is not hello world
My Name is not hello world

相关内容