我有一个文件,我的任务是读取该文件并为每一行生成一个新文件。新生成的文件的名称应来自该行内容。
例子
该文件有这两行:
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
:
在程序中执行此类重定向时awk
,awk
将保持文件打开状态,直到读取所有数据后退出。每个打开的文件都需要一个文件描述符,并且文件描述符的数量有限。如果许多必须写入文件,最好显式关闭文件:
awk '{ print >>$4; close($4) }' <file.txt
在这里,我们打开输出进行追加(而不是截断和覆盖),将当前行写入文件并关闭文件。当第二次打开同一文件进行输出时(因为字段 4 恰好在两行或更多行中相同),将附加数据。如果我们使用>$4
,新数据就会覆盖旧数据。这在顶部的第一个程序中不是问题,因为我们从未明确关闭文件。
脚本(或任何调用awk
程序的程序)必须在运行之前将输出文件设置为空或不存在,具体取决于具体情况。
删除文件hello
和not
,并运行上述命令三次:
$ 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