基于条件拆分linux文件
我在基于条件拆分linux文件,linux,bash,awk,Linux,Bash,Awk,我在linux中有一个文件。该文件的内容如下 Test_12 Test_abc start_1 start_abcd end_123 end_abcde_12 现在,我想根据第一个下划线 输出: 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" >
linux
中有一个文件。该文件的内容如下
Test_12
Test_abc
start_1
start_abcd
end_123
end_abcde_12
现在,我想根据第一个下划线
输出:
- 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
读取-r行时;做
回显“$line”>>“${line}.txt”
完成
但我每行都有文件
我在这里做错了什么?如何获得所需的输出?最好使用awk:
awk -F_ 'p && $1 != p{close(fn)} {p=$1; fn=p ".txt"; print>>fn} END{close(fn)}' split.txt
当第一列中的值发生变化时,关闭文件只需要一点额外的处理,这样,如果您的输入文件很大,我们就不会有太多打开的文件。最好使用awk:
awk -F_ 'p && $1 != p{close(fn)} {p=$1; fn=p ".txt"; print>>fn} END{close(fn)}' split.txt
当第一列中的值发生变化时,关闭文件只需要一点额外的处理,这样,如果您的输入文件很大,我们就不会有太多打开的文件。您需要修剪每行的下划线和尾随文本<代码>%%.*执行以下操作:
while read -r line ; do
echo "$line" >> "${line%%_*}.txt"
done < split.txt
读取-r行时;做
回显“$line”>>“${line%%.*}.txt”
完成
说明:
:修剪尾随文本%
:查找最长的匹配项%%
:下划线和后面的所有内容。*
while read -r line ; do
echo "$line" >> "${line%%_*}.txt"
done < split.txt
读取-r行时;做
回显“$line”>>“${line%%.*}.txt”
完成
说明:
:修剪尾随文本%
:查找最长的匹配项%%
:下划线和后面的所有内容。*
awk -F'_' '{print > ($1".txt")}' file
awk -F'_' '{f=$1".txt"; print > f} f!=p{close(p); p=f}' file
否则,对于其他AWK,如果您的输入文件按问题中所示的第一个字段分组,则您只需要:
awk -F'_' '{print > ($1".txt")}' file
awk -F'_' '{f=$1".txt"; print > f} f!=p{close(p); p=f}' file
如果不是这样,那么它的效率会稍低,因为您可能需要重新打开以前关闭的文件(因此使用>
而不是
):
阅读,然后使用awk
有了GNU awk,您只需要:
awk -F'_' '{print > ($1".txt")}' file
awk -F'_' '{f=$1".txt"; print > f} f!=p{close(p); p=f}' file
否则,对于其他AWK,如果您的输入文件按问题中所示的第一个字段分组,则您只需要:
awk -F'_' '{print > ($1".txt")}' file
awk -F'_' '{f=$1".txt"; print > f} f!=p{close(p); p=f}' file
如果不是这样,那么它的效率会稍低,因为您可能需要重新打开以前关闭的文件(因此使用>
而不是
):
你能试试这个吗
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
你能试试这个吗
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
我可能误读了,但我认为1美元永远也不可能等于fn。最后你不需要关闭(),顺便说一句,awk默认是这样做的。我可能误读了它,但我认为$1永远不可能等于fn。最后,您不需要关闭(),顺便说一句,默认情况下-awk会这样做。这将去除每行的所有前导和尾随空格,这可能不是OP所期望的(特别是尾随空格)。始终在读取时设置
IFS=
,除非您心中有一个特定的目标,需要将其设置为。它也将比等效的awk脚本慢一个数量级,并将根据路径中的echo
版本产生不同的输出。请注意,这会将每行的所有前导和尾随空格都去掉,这可能不是OP所期望的(尤其是尾随空格)。始终在读取时设置IFS=
,除非您心中有一个特定的目标,需要将其设置为。它也将比等效的awk脚本慢一个数量级,并将根据路径中的echo
版本产生不同的输出。看见