我有很多行数不同的编号 *.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