我写了这段代码。
目标如下:
对于临时列表中的每个文件,它应该首先出现列表,将其放入名为$name1
的变量中,然后将列表的第二次出现到名为$name2
的第二个变量中。变量是文件名。使用2个变量,我做了一个连接。
for files in $(cat temp.lst); do
if [ $(cat temp.lst | wc -l) == 1 ]
then
name=$(head -1 temp.lst)
join -t\; -j 1 file_minus1.txt "$name" | sed 's/;;/;/g' > file1.txt
else
name1=$(head -1 temp.lst)
name2=$(head -2 temp.lst)
echo "var1 "$name1 "var2 "$name2
sed '1,2d' temp.lst > tmpfile.txt
mv tmpfile.txt temp.lst
join -t\; -j 1 "$name1" "$name2" | sed 's/;;/;/g' > file_minus1.txt
fi
;done
从理论上讲,它应该可行,但在这里它不起作用,唉。
我在代码中输入的echo
行给了我3个变量而不是2个
var1 ei_etea17_m.tsv var2 ei_etea17_m.tsv ei_eteu25_m.tsv
更糟糕的是,加入并没有按照我想象的方式运行,而是给我这个错误代码
join: ei_etea17_m.tsv
ei_eteu25_m.tsv: No such file or directory
请查看我的temp.lst
ei_eteu27_m.tsv
ei_eteu28_m.tsv
ei_isbr_m.tsv
ei_isbu_m.tsv
ei_isin_m.tsv
欢迎任何建议。
最佳。
答案 0 :(得分:3)
要在循环中提取文件的2行,请尝试以下操作:
paste - - < temp.lst |
while read name1 name2; do
if [[ -z $name2 ]]; then
name2=$name1
name1=file_minus1.txt
output=file1.txt
else
output=file_minus1.txt
fi
join -t\; "$name1" "$name2" | sed 's/;;/;/g' > $output
done
注释
paste
命令从文件中取出2行,并将它们连接成一行(由制表符分隔)
seq 7 | paste - -
read
可以分配给多个变量:该行将在空格上拆分(默认)并分配给命名变量。答案 1 :(得分:1)
要执行n
- 方式连接,请使用递归:)
recursive_join () {
# Zero files: do nothing (special case)
# One file: output it
# Multiple files: join the first with the result of joining the rest
file1=$1
shift || return
[ "$#" -eq 0 ] && cat "$file1" ||
recursive_join "$@" | join -t\; -j1 "$file1" -
}
recursive_join ei_eteu27_m.tsv ei_eteu28_m.tsv ei_isbr_m.tsv ei_isbu_m.tsv ei_isin_m.tsv
对此进行调整以使用列出输入文件的文件,而不是使用命令行参数,这是一个小问题。只要没有输入文件名包含空格或其他特殊字符,您只需使用
即可recursive_join $(cat temp.lst)
或者,如果您想利用bash
功能,可以使用数组:
while read; do files+=("$REPLY"); done < temp.lst
recursive_join "${files[@]}"
或bash
4:
readarray files < temp.list
recursive_join "${files[@]}"
但是,如果您只想坚持使用标准shell脚本,最好修改递归函数以从标准输入读取输入文件名。这使得函数变得更加丑陋,因为为了检测标准输入上是否只剩下一个文件,我们必须尝试读取第二个文件,如果成功则将其放回标准输入。
recursive_join () {
IFS= read -r file1 || return
IFS= read -r file2 &&
{ echo "$file2"; cat; } | recursive_join | join -t\; -j1 "$file1" - ||
cat "$file1"
}
recursive_join < temp.lst
创建一个可以使用 命令行参数或从标准输入读取列表的函数留给读者练习。
答案 2 :(得分:0)
变量name1获得第一行。 变量name2获得前两行。 如果你想让name2只有第二行你可以试试像:
name2=$(sed -n '2p')
同样sed -i将不再需要tmpfile.txt。
答案 3 :(得分:0)
Ok Gents或Ladies。
我发现了为什么。
head -1 temp.lst
仅提供没有扩展名的文件名。
我需要找到一种方法来包含扩展名。可行的。