在bash上逐行读取文件;每行包含另一个unqiue文件的路径

时间:2019-01-17 21:55:53

标签: bash shell vim

给定文件' a.txt '中的每一行都包含另一个唯一文件的目录/路径。假设我们要逐行解析“ a.txt ”,以字符串格式提取路径,然后使用诸如vim之类的工具在此路径下处理文件,依此类推。

经过这个线程-Read a file line by line assigning the value to a variable之后,我在bash上写了以下脚本,说“ open-file.sh ”(是我的新手)

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
  vim -c ":q" -cq $line # Just open the file and close it using :q 
done < "$1"

然后我们将上述脚本运行为-

./open-file.sh a.txt

问题是,尽管$ line正确指定了新文件的路径,但是当vim打开文件时,vim继续以命令的形式接收' a.txt '中包含的文本。如何编写一个脚本,在这里我可以正确地从' a.txt '获取路径,使用vim打开它,然后继续解析' a.txt 中的其余行>'?

3 个答案:

答案 0 :(得分:2)

替换:

vim -c ":q" -cq $line

使用:

vim -c ":q" -cq "$line" </dev/tty

重定向</dev/tty告诉vim从终端获取其标准输入。否则,vim的标准输入为"$1"

此外,优良作法是将$line放在双引号中以防止分词等。

最后,虽然vim非常适合进行交互工作,但是如果最终目标是对每个文件进行全自动处理,则您可能需要考虑使用sedawk之类的工具。

答案 1 :(得分:0)

尽管我不确定您的最终目标,但是此shell命令将在2 3 4 5 11 12 13 14 15 16 17 18 19 中每行执行一次vim:

a.txt

正如对Read a file line by line assigning the value to a variable的评论中所述,您遇到的问题是由于vim是一个交互式程序,因此继续从xargs -o -n1 vim -c ':q' < a.txt读取输入。

答案 2 :(得分:0)

问题出在您基于脚本的答案下的already mentioned in a comment

vim正在消耗stdin,它由done < $1赋予循环。在下面的示例中,我们可以观察到相同的行为:

$ while read i; do cat; done < <(seq 3)
2
3

<(seq 3)用三行123模拟文件。而不是三个静默迭代,我们只能得到一个迭代,并且输出为23

stdin不仅在循环头传递给read,而且在循环体传递给cat。因此,read读取一行,进入循环,cat读取所有剩余的行,stdin为空,read不再需要读取,循环退出。

您可以通过将某些内容重定向到vim来解决问题,但是还有更好的方法。您根本不需要循环:

< "$1" xargs -d\\n -n1 vim -c :q -cq

xargs将对vim给定的文件中的每一行执行一次$1