通过shell循环逐行读取两个txt文件,将两个不同文建内容拼成一个新文件txt

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过shell循环逐行读取两个txt文件,将两个不同文建内容拼成一个新文件txt相关的知识,希望对你有一定的参考价值。

老文件分割符为 '|',文件1内容:1|2|3|4|5文件二内容:5|6|7|5|9|需要的文件内容:1|2|3|4|5|9

可以试试cstdiofile类
使用cstdiofile的readstring方法可以一次读取一行,如果前面无用数据的长度是固定的,读取一行后可以再读取第i个字符后的字符串,就可以获得你所需要的数据了,或者使用afxextractsubstring来获得用空格分隔的字符串的某个位置的数据
读取多个文件的话可以用一个循环来读取,读取前先用getstatus方法来判断文件是否存在。
参考技术A 首先确定一下你的日志文件在哪
比如在
/var/logs
#!/bin/bash
cat
/var/logs/log1
>
/var/logs/newlog
tail
-n
5
/var/logs/log2
>>
/var/logs/newlog

如何逐行合并两个文件

【中文标题】如何逐行合并两个文件【英文标题】:How to merge two files consistently line by line 【发布时间】:2013-04-29 22:31:45 【问题描述】:

我有两个文件(file1.txt & file2.txt)。这些文件只是示例。

如何合并这两个文件以创建文件 - merge_files.txt 如示例 3?

我现在正在编写一个KornShell (ksh) 脚本,因此可以使用 KornShell、AWK、sed、Perl 单线等进行合并。

背景 - 为什么我需要合并文件:我的目标是将 old 文件(存在于第一个字段中)重命名为 new 文件(存在于第二个字段中)字段)。

示例 1

文件 file1.txt

/etc/port1-192.9.200.1-255.555.255.0
/etc/port2-192.9.200.1-255.555.255.0
/etc/port3-192.9.200.1-255.555.255.0
/etc/port4-192.9.200.1-255.555.255.0
/etc/port5-192.9.200.1-255.555.255.0
.
.
.
.

示例 2

文件 file2.txt

/etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.90.2.1-255.555.0.0
.
.
.
.

示例 3

文件 merge_files.txt

/etc/port1-192.9.200.1-255.555.255.0  /etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.9.200.1-255.555.255.0  /etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.9.200.1-255.555.255.0  /etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.9.200.1-255.555.255.0  /etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.9.200.1-255.555.255.0  /etc/port5-192.90.2.1-255.555.0.0
.
.
.
.
.

示例 4(merge_files.txt 结构)

first field                           second field

OLD file                              NEW file

【问题讨论】:

这两个文件的长度总是一样吗? (你最终的目标只是重命名文件,重命名文件后你会删除merge_files.txt?) 不,这只是示例(长度或路径可能更不同),文件内容也可能不同(无需删除 merge_files.txt) 【参考方案1】:

这个 Perl 单行代码将显示必要的重命名:

perl -e 'open $f[$_-1], "file$_.txt" for 1,2; print "rename @n\n" while chomp(@n = map ''.<$_>, @f)'

如果这对您有用,则将 print 语句替换为真正的重命名并使用

perl -e 'open $f[$_-1], "file$_.txt" for 1,2; rename @n while chomp(@n = map ''.<$_>, @f)'

进行实际的重命名。

【讨论】:

【参考方案2】:

您可以使用paste 并排格式化文件:

$ paste -d" " file1.txt file2.txt
/etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0

例如:

$ paste -d" " file1.txt file2.txt | while read from to; do echo mv "$from" "$to"; done
mv /etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
mv /etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
mv /etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
mv /etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
mv /etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0

当然,您会想要进行一些安全检查([ -f "$from" ],...)。

免责声明:仅当您的文件名中没有空格时才有效。

【讨论】:

在 linux 和 solaris 中定义的粘贴命令? ,因为我的脚本将在两个操作系统(linux 和 solaris)上运行 paste 可在任何符合POSIX 的系统上使用,并且Linux 和Solaris 都附带它(here 是Oracle 网站上的Solaris 手册页),因此这是一个可移植的解决方案。 如何并排粘贴文件,中间没有空格?即,使用paste -d" " file1.txt file2.txt - 没有空格分隔符? - 提前致谢! @VikasGoel paste -d'\0'(见pubs.opengroup.org/onlinepubs/9699919799/utilities/…)。 有批处理(Windows)等效方法吗?【参考方案3】:
paste -d " " file1.txt file2.txt

非常适合这份工作。

但如果您在 Windows 环境中处理文本文件并使用 GNU paste,请确保将文件转换为 Unix 格式 (CR) 并且不要使用带有 (CR-LF) 的文件。

GNU paste 似乎不能正确处理 DOS 格式,并且解析是不可预测的。预期的输出不稳定且出乎意料,没有警告。

您可以使用gVim 轻松转换它们(菜单编辑文件设置文件格式)。

【讨论】:

有批处理(Windows)等效方法吗?【参考方案4】:

实现 OP 重命名编号文件目标的完全不相关的方法:

for f in 1..5; do mv /etc/port$d-192.9.200.1-255.555.255.0 /etc/port$d-192.90.2.1-255.555.0.0; done

基于rename的另一种可能性

rename 's/192.9.200.1/192.90.2.1/' /etc/port[1-5]-192.9.200.1-255.555.255.0

【讨论】:

问题是合并文件内容,而不是重命名【参考方案5】:

命令

paste file1 file2

输出

/etc/port1-192.9.200.1-255.555.255.0    /etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.9.200.1-255.555.255.0    /etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.9.200.1-255.555.255.0    /etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.9.200.1-255.555.255.0    /etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.9.200.1-255.555.255.0    /etc/port5-192.90.2.1-255.555.0.0

【讨论】:

【参考方案6】:

这是在 Windows CMD 中合并文件的示例代码:

: Count number of lines to merge
for /f "tokens=*" %i in ('find /c /v "" ^< test2.txt') do set /a n=%i<nul

: Read 2 files & merge line by line
for /l %a in (1,1,%n%) do (
for /f "tokens=*" %i in ('find /v /n "" ^< test1.txt ^| find "[%a]"') do (
for /f "tokens=*" %j in ('find /v /n "" ^< test2.txt ^| find "[%a]"') do (
set a=%i
set b=%j
set a=!a:*]=!
set b=!b:*]=!
echo:!a! -- !b!
)))

【讨论】:

它不能与缩进一起使用吗?

以上是关于通过shell循环逐行读取两个txt文件,将两个不同文建内容拼成一个新文件txt的主要内容,如果未能解决你的问题,请参考以下文章

如何在Shell脚本中逐行读取文件

Bash怎么逐行读取一个文件

DELPHI中逐行读取并复制

shell:逐行读取文件内容

Shell脚本for循环逐行原样输出

shell 流程控制