如何将一个文本文件分割成若干个具有一定格式的文件



我有一个这样的数据

POW076956-1 CC1=CC=C(C=C1)C(=O)N1N=C(CC1C1=CC=CO1)C1=CC=C(NS(C)(=O)=O)C=C1
POW000136-2 CCCCOC1=CC=C(OCCCC)C2=C1NC1(N2)C(=O)NC2=CC=C(C=C12)[N+]([O-])=O
POW192689-1 CC(C)(C)C1=CC=C(C=C1)C1N(CCN2C=CC=C12)S(=O)(=O)C1=CC=C2C=CC=CC2=C1
POW005144-1 CC1=CC=C2N=C(OC2=C1)C1=CC=C(NC(=O)C2=CC=C(I)C=C2)C=C1
POW146687-1 O=S(=O)(C1=CC=CC=C1)C1=CC=C(COC2=CC=CC3=CC=CN=C23)C=C1
POW008940-2 OC(CNC1=CC=CC=C1)CN1C2=CC=C(I)C=C2C2=C1C=CC(I)=C2

我想把每一行的第二部分和第一部分的名字放在一个文件中,格式为。txt

例如

CC1=CC=C(C=C1)C(=O)N1N=C(CC1C1=CC=CO1)C1=CC=C(NS(C)(=O)=O)C=C1

放入文件

保存文件名为POW076956-1.txt

awk '{print $2 > $1".txt"}' input_file
find . -name "*.txt"
./POW000136-2.txt
./POW005144-1.txt
./POW008940-2.txt
./POW076956-1.txt
./POW146687-1.txt
./POW192689-1.txt
cat ./POW000136-2.txt
CCCCOC1=CC=C(OCCCC)C2=C1NC1(N2)C(=O)NC2=CC=C(C=C12)[N+]([O-])=O

就我个人而言,我将使用awk,但是您已经标记了问题[bash],因此bash解决方案一次读取整行,然后使用参数展开并删除子字符串将行分隔为两部分,这很容易完成。

假设您提供要读取的文件名作为程序的第一个参数,可以这样做:

## loop reading each line
while read -r line || [ -n "$line" ]; do
## separate with parameter expansion & redirect to file
printf "%sn" "${line#* }" > "${line%% *}"
done < "$1"

从左和右(前和后)裁剪的参数展开总结如下:

${var#pattern}      # Strip shortest match of pattern from front of $var
${var##pattern}     # Strip longest match of pattern from front of $var
${var%pattern}      # Strip shortest match of pattern from back of $var
${var%%pattern}     # Strip longest match of pattern from back of $var

您将希望对提供给程序的filename参数执行几个验证。首先,您希望检查至少提供了一个参数,其次,您希望验证参数是一个有效的文件名,并且该文件是非空的。把它们放在一起,你可以这样做:

#!/bin/bash
[ -z "$1" ] && {  ## validate 1 argument given for filename
printif "error: filename required.nusage: %s filen" "./${0##*/}" >&2
exit 1
}
[ -s "$1" ] || {  ## validate file exists and is non-empty
printf "error: file doesn't exist or is empty.n" >&2
exit 1
}
## loop reading each line
while read -r line || [ -n "$line" ]; do
## separate with parameter expansion & redirect to file
printf "%sn" "${line#* }" > "${line%% *}"
done < "$1"

使用/输出示例

使用名为file的文件中的示例输入和splitfile.sh中的脚本,您可以执行:
$ bash splitfile.sh file

创建的结果文件:

$ ls -al POW*
-rw-r--r-- 1 david david 64 May  4 19:53 POW000136-2
-rw-r--r-- 1 david david 54 May  4 19:53 POW005144-1
-rw-r--r-- 1 david david 50 May  4 19:53 POW008940-2
-rw-r--r-- 1 david david 63 May  4 19:53 POW076956-1
-rw-r--r-- 1 david david 55 May  4 19:53 POW146687-1
-rw-r--r-- 1 david david 67 May  4 19:53 POW192689-1

列出的第一个文件的示例内容:

$ cat POW000136-2
CCCCOC1=CC=C(OCCCC)C2=C1NC1(N2)C(=O)NC2=CC=C(C=C12)[N+]([O-])=O

注意:对于只有几千行或一万行左右的输入文件,使用bash脚本就可以了。对于百万行或更多行,使用awk(或sed)。shell脚本和适当的实用程序在处理大文件方面的效率差异随着文件大小的增加而增加。

应该这样做:

#!/usr/bin/env bash
while read -r file data; do
echo "$data" > "$file.txt"
done < 'input'

最新更新