根据条件

时间:2017-09-21 18:35:25

标签: linux bash awk

我在linux中有一个文件。该文件的内容如下。

Test_12
Test_abc
start_1
start_abcd
end_123
end_abcde_12

现在我想根据第一个underscore之后的匹配字符串将文件拆分成多个小文件

输出继电器:

  • Test.txt的:

    Test_12
    Test_abc
    
  • start.txt:

    start_1
    start_abcd  
    
  • end.txt:

    end_123
    end_abcde_12
    

我试过以下

while read -r line ; do
    echo "$line" >> "${line}.txt"  
done < split.txt

但我得到了每行的文件。

我在这里做错了什么,如何获得我想要的输出?

4 个答案:

答案 0 :(得分:2)

最好使用awk:

awk -F_ 'p && $1 != p{close(fn)} {p=$1; fn=p ".txt"; print>>fn} END{close(fn)}' split.txt

当第一列中的值发生变化时,关闭文件会有一些额外的处理,这样如果您的输入文件很大,我们就不会有太多打开的文件。

答案 1 :(得分:1)

您需要修剪每行的下划线和尾随文本。 %%_*这样做:

while read -r line ; do
    echo "$line" >> "${line%%_*}.txt"  
done < split.txt

说明:

  • %:修剪尾随文字
  • %%:找到最长的匹配
  • _*:下划线以及
  • 之后的所有内容

答案 2 :(得分:0)

阅读why-is-using-a-shell-loop-to-process-text-considered-bad-practice,然后使用awk。

使用GNU awk,您只需要:

awk -F'_' '{print > ($1".txt")}' file

否则与其他awks一样,如果您的输入文件按照问题中显示的第一个字段进行分组,那么您只需要:

awk -F'_' '{f=$1".txt"; print > f} f!=p{close(p); p=f}' file

如果它不是,那么效率稍低,因为您可能需要重新打开之前关闭的文件(因此>>而不是> ):

awk -F'_' '{f=$1".txt"; print >> f} f!=p{close(p); p=f}' file

答案 3 :(得分:0)

你可以试试这个:

while read line; do
    content=`echo $line|awk 'BEGIN{FS="_"}{print $1}'`
    for f in *; do
        filename=`echo $f|awk 'BEGIN{FS="."}{print $1}'`
        if [ "$content" == "$filename" ]; then
            echo $line>>$f
            break
        else
            echo $line>>$content.txt
            break
        fi
    done
done< file.txt

输出:

bash-4.4$ ls -lrt
total 12
-rw-r--r-- 1 21726 21726 978 Sep 22 04:54 README.txt
-rw-r--r-- 1 21726 21726  49 Sep 22 04:56 file.txt
-rwxr-xr-x 1 21726 21726 252 Sep 22 05:06 script.sh
bash-4.4$ cat file.txt
Test_12
Test_abc
Start_1
Start_abc
end_1
end_abc
bash-4.4$ ./script.sh
bash-4.4$ ls -lrt
total 24
-rw-r--r-- 1 21726 21726 978 Sep 22 04:54 README.txt
-rw-r--r-- 1 21726 21726  49 Sep 22 04:56 file.txt
-rwxr-xr-x 1 21726 21726 252 Sep 22 05:06 script.sh
-rw-r--r-- 1 21726 21726  17 Sep 22 05:06 Test.txt
-rw-r--r-- 1 21726 21726  18 Sep 22 05:06 Start.txt
-rw-r--r-- 1 21726 21726  14 Sep 22 05:06 end.txt
bash-4.4$ cat Start.txt
Start_1
Start_abc
bash-4.4$ cat Test.txt
Test_12
Test_abc
bash-4.4$ cat end.txt
end_1
end_abc