![循环编号文件并在文件的每一行附加具有相同编号的另一个文件的内容](https://linux22.com/image/158630/%E5%BE%AA%E7%8E%AF%E7%BC%96%E5%8F%B7%E6%96%87%E4%BB%B6%E5%B9%B6%E5%9C%A8%E6%96%87%E4%BB%B6%E7%9A%84%E6%AF%8F%E4%B8%80%E8%A1%8C%E9%99%84%E5%8A%A0%E5%85%B7%E6%9C%89%E7%9B%B8%E5%90%8C%E7%BC%96%E5%8F%B7%E7%9A%84%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E5%86%85%E5%AE%B9.png)
我有很多行数不同的编号 *.csv 文件和同样多的 *.txt 文件。我想在文件 1.csv 的每一行附加文件 1.txt 的内容,在文件 2.csv 的每一行附加文件 2.txt 的内容,依此类推。每个 *.txt 文件仅包含一行。
我尝试过的:
for i in {1..2}; do for j in {1..2}; do perl -i -p -e "s/^(.+?)$/\1<content of $j.txt>/g" ./$i.csv; done; done
但显然这是行不通的。
示例(初始情况):
1.csv
line 1
line 2
line 3
2.csv
line 1
line 2
1.txt
yyy
2.txt
zzz
结果(应该是):
1.csv
line 1yyy
line 2yyy
line 3yyy
2.csv
line 1zzz
line 2zzz
1.txt
yyy
2.txt
zzz
任何帮助,将不胜感激。
答案1
也许要扩展你的 perl 尝试
for f in ./*.csv; do
perl -i -lpe 'BEGIN{$x = shift @ARGV} s/$/$x/' "$(<"${f%.csv}.txt")" "$f"
done
(假设操作符为 ksh/zsh/bash ;如果您的 shell 不支持,$(<file)
请替换为)。$(cat<file)
给予
$ head ./*.csv
==> ./1.csv <==
line 1yyy
line 2yyy
line 3yyy
==> ./2.csv <==
line 1zzz
line 2zzz
但是,您实际上并不需要正则表达式替换 - 您可以考虑s/$/$x/
用简单的字符串连接替换$_ .= $x
答案2
使用awk
:
for f in *.csv; do
awk '
FNR==NR{txt=$0}
FNR!=NR{printf "%s%s\n",$0,txt}
' "${f%.*}.txt" "$f" > "$f.csv.tmp" && mv "$f.csv.tmp" "$f"
done
输出:
$ cat a.csv
line 1yyy
line 2yyy
line 3yyy
一些现代的实现awk
有-i inplace
选项,所以你不需要“tmp 和mv
部分”。看这里。
答案3
A-sed
单线:
for i in 1 2 ; do sed -i "s/$/$(cat $i.txt)/" $i.csv ; done
s/$/
我正在替换每行的末尾,从而附加到该行
$(cat $i.txt)
追加以当前号码命名的文本文件。
filen.txt
请注意,如果包含斜杠、反斜杠、引号等特殊字符,这将导致问题。
如果这是一个问题,请使用ascii 记录分隔符而不是/
sed 语句中的 。您可以通过按 Ctrl+V 在 vim 中输入这些内容,然后输入它们的十进制值 --- 在本例中为 030